2 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * This file is part of <starter>
5 * Written by <Seungtaek Chung> <seungtaek.chung@samsung.com>, <Mi-Ju Lee> <miju52.lee@samsung.com>, <Xi Zhichan> <zhichan.xi@samsung.com>
7 * PROPRIETARY/CONFIDENTIAL
9 * This software is the confidential and proprietary information of SAMSUNG ELECTRONICS ("Confidential Information").
10 * You shall not disclose such Confidential Information and shall use it only in accordance
11 * with the terms of the license agreement you entered into with SAMSUNG ELECTRONICS.
12 * SAMSUNG make no representations or warranties about the suitability of the software,
13 * either express or implied, including but not limited to the implied warranties of merchantability,
14 * fitness for a particular purpose, or non-infringement.
15 * SAMSUNG shall not be liable for any damages suffered by licensee as a result of using,
16 * modifying or distributing this software or its derivatives.
20 #include <Elementary.h>
23 #include <vconf-keys.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
35 #include <sys/param.h>
38 #include "lockd-debug.h"
39 #include "lock-daemon.h"
40 #include "lockd-process-mgr.h"
42 static int phone_lock_pid;
45 int phone_lock_app_pid;
55 #define VCONFKEY_PHONE_LOCK_VERIFICATION "memory/lockscreen/phone_lock_verification"
56 #define PHLOCK_SOCK_PREFIX "/tmp/phlock"
57 #define PHLOCK_SOCK_MAXBUFF 65535
58 #define PHLOCK_APP_CMDLINE "/opt/apps/org.tizen.phone-lock/bin/phone-lock"
60 static void lockd_launch_app_lockscreen(struct lockd_data *lockd);
62 static void _lockd_notify_pm_state_cb(keynode_t * node, void *data)
64 LOCKD_DBG("PM state Notification!!");
66 struct lockd_data *lockd = (struct lockd_data *)data;
70 LOCKD_ERR("lockd is NULL");
74 if (vconf_get_int(VCONFKEY_PM_STATE, &val) < 0) {
75 LOCKD_ERR("Cannot get VCONFKEY_PM_STATE");
79 if (val == VCONFKEY_PM_STATE_LCDOFF) {
80 lockd_launch_app_lockscreen(lockd);
85 _lockd_notify_lock_state_cb(keynode_t * node, void *data)
87 LOCKD_DBG("lock state changed!!");
89 struct lockd_data *lockd = (struct lockd_data *)data;
93 LOCKD_ERR("lockd is NULL");
97 if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
98 LOCKD_ERR("Cannot get VCONFKEY_IDLE_LOCK_STATE");
102 if (val == VCONFKEY_IDLE_UNLOCK) {
103 LOCKD_DBG("unlocked..!!");
108 _lockd_notify_phone_lock_verification_cb(keynode_t * node, void *data)
110 LOCKD_DBG("%s, %d", __func__, __LINE__);
112 struct lockd_data *lockd = (struct lockd_data *)data;
116 LOCKD_ERR("lockd is NULL");
120 if (vconf_get_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, &val) < 0) {
121 LOCKD_ERR("Cannot get VCONFKEY_PHONE_LOCK_VERIFICATION");
126 vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
130 static void lockd_launch_app_lockscreen(struct lockd_data *lockd)
132 LOCKD_DBG("launch app lock screen");
134 int call_state = -1, bootlock_state = -1;
136 vconf_get_bool(VCONFKEY_SETAPPL_STATE_POWER_ON_LOCK_BOOL,
139 if (bootlock_state) {
140 lockd->phone_lock_state = 1;
142 lockd->phone_lock_state = 0;
145 vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
146 if (call_state != VCONFKEY_CALL_OFF) {
148 ("Current call state(%d) does not allow to launch lock screen.",
153 if (lockd->phone_lock_state == 1) {
154 vconf_set_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, FALSE);
155 /* Check phone lock application is already exit */
156 if (lockd_process_mgr_check_lock(lockd->phone_lock_app_pid) == TRUE) {
157 LOCKD_DBG("phone lock App is already running.");
160 vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_LOCK);
161 lockd->phone_lock_app_pid =
162 lockd_process_mgr_start_phone_lock();
163 phone_lock_pid = lockd->phone_lock_app_pid;
164 LOCKD_DBG("%s, %d, phone_lock_pid = %d", __func__, __LINE__,
169 inline static void lockd_set_sock_option(int fd, int cli)
172 struct timeval tv = { 1, 200 * 1000 };
174 size = PHLOCK_SOCK_MAXBUFF;
175 setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
176 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
178 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
181 static int lockd_create_sock(void)
183 struct sockaddr_un saddr;
186 fd = socket(AF_UNIX, SOCK_STREAM, 0);
188 if (errno == EINVAL) {
189 fd = socket(AF_UNIX, SOCK_STREAM, 0);
192 ("second chance - socket create error");
196 LOCKD_DBG("socket error");
201 bzero(&saddr, sizeof(saddr));
202 saddr.sun_family = AF_UNIX;
204 strncpy(saddr.sun_path, PHLOCK_SOCK_PREFIX, strlen(PHLOCK_SOCK_PREFIX));
205 saddr.sun_path[strlen(PHLOCK_SOCK_PREFIX)] = 0;
207 unlink(saddr.sun_path);
209 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
210 LOCKD_DBG("bind error");
214 if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
215 LOCKD_DBG("failed to change the socket permission");
219 lockd_set_sock_option(fd, 0);
221 if (listen(fd, 10) == -1) {
222 LOCKD_DBG("listen error");
229 static gboolean lockd_glib_check(GSource * src)
234 fd_list = src->poll_fds;
236 tmp = (GPollFD *) fd_list->data;
237 if ((tmp->revents & (POLLIN | POLLPRI)))
239 fd_list = fd_list->next;
245 static char *lockd_read_cmdline_from_proc(int pid)
249 char *cmdline = NULL, *tempptr = NULL;
252 snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
254 fp = fopen(path, "r");
256 LOCKD_DBG("Cannot open cmdline on pid[%d]", pid);
260 cmdline = malloc(32);
261 if (cmdline == NULL) {
262 LOCKD_DBG("%s", "Out of memory");
267 bzero(cmdline, memsize);
268 if (fgets(cmdline, 32, fp) == NULL) {
269 LOCKD_DBG("%s", "Cannot read cmdline");
275 while (cmdline[memsize - 2] != 0) {
276 cmdline[memsize - 1] = (char)fgetc(fp);
277 tempptr = realloc(cmdline, memsize + 32);
278 if (tempptr == NULL) {
280 LOCKD_DBG("%s", "Out of memory");
284 bzero(cmdline + memsize, 32);
285 fgets(cmdline + memsize, 32, fp);
294 static int lockd_sock_handler(int fd)
300 char cmd[PHLOCK_SOCK_MAXBUFF];
301 char *cmdline = NULL;
304 struct sockaddr_un lockd_addr;
307 sun_size = sizeof(struct sockaddr_un);
310 accept(fd, (struct sockaddr *)&lockd_addr,
311 (socklen_t *) & sun_size)) == -1) {
313 LOCKD_DBG("accept error");
317 if (getsockopt(clifd, SOL_SOCKET, SO_PEERCRED, &cr, (socklen_t *) & cl)
319 LOCKD_DBG("peer information error");
323 LOCKD_DBG("Peer's pid=%d, uid=%d, gid=%d\n", cr.pid, cr.uid, cr.gid);
325 memset(cmd, 0, PHLOCK_SOCK_MAXBUFF);
327 lockd_set_sock_option(clifd, 1);
329 len = recv(clifd, cmd, PHLOCK_SOCK_MAXBUFF, 0);
332 LOCKD_DBG("recv error, cmd is NULL");
337 if (len != strlen(cmd)) {
338 LOCKD_DBG("recv error %d %d", len, strlen(cmd));
343 LOCKD_DBG("cmd %s", cmd);
345 cmdline = lockd_read_cmdline_from_proc(cr.pid);
346 if (cmdline == NULL) {
347 LOCKD_DBG("Error on opening /proc/%d/cmdline", cr.pid);
351 LOCKD_DBG("/proc/%d/cmdline : %s", cr.pid, cmdline);
353 if ((!strncmp(cmdline, PHLOCK_APP_CMDLINE, strlen(cmdline)))
354 && (phone_lock_pid == cr.pid)) {
355 LOCKD_DBG("pid [%d] %s is verified, unlock..!!\n", cr.pid,
357 lockd_process_mgr_terminate_phone_lock(phone_lock_pid);
359 vconf_set_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, TRUE);
365 static gboolean lockd_glib_handler(gpointer data)
367 GPollFD *gpollfd = (GPollFD *) data;
368 if (lockd_sock_handler(gpollfd->fd) < 0) {
369 LOCKD_DBG("lockd_sock_handler is failed..!!");
374 static gboolean lockd_glib_dispatch(GSource * src, GSourceFunc callback,
381 static gboolean lockd_glib_prepare(GSource * src, gint * timeout)
386 static GSourceFuncs funcs = {
387 .prepare = lockd_glib_prepare,
388 .check = lockd_glib_check,
389 .dispatch = lockd_glib_dispatch,
393 static int lockd_init_sock(void)
400 fd = lockd_create_sock();
402 LOCKD_DBG("lock daemon create sock failed..!!");
405 src = g_source_new(&funcs, sizeof(GSource));
407 gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
408 gpollfd->events = POLLIN;
411 g_source_add_poll(src, gpollfd);
412 g_source_set_callback(src, (GSourceFunc) lockd_glib_handler,
413 (gpointer) gpollfd, NULL);
414 g_source_set_priority(src, G_PRIORITY_LOW);
416 ret = g_source_attach(src, NULL);
425 static void lockd_init_vconf(struct lockd_data *lockd)
429 if (vconf_notify_key_changed
430 (VCONFKEY_PM_STATE, _lockd_notify_pm_state_cb, lockd) != 0) {
431 LOCKD_ERR("Fail vconf_notify_key_changed : VCONFKEY_PM_STATE");
434 if (vconf_notify_key_changed
435 (VCONFKEY_PHONE_LOCK_VERIFICATION,
436 _lockd_notify_phone_lock_verification_cb, lockd) != 0) {
437 if (vconf_get_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, &val) < 0) {
439 ("Cannot get VCONFKEY_PHONE_LOCK_VERIFICATION");
440 vconf_set_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, 0);
441 if (vconf_notify_key_changed
442 (VCONFKEY_PHONE_LOCK_VERIFICATION,
443 _lockd_notify_phone_lock_verification_cb,
446 ("Fail vconf_notify_key_changed : VCONFKEY_PHONE_LOCK_VERIFICATION");
450 ("Fail vconf_notify_key_changed : VCONFKEY_PHONE_LOCK_VERIFICATION");
454 if (vconf_notify_key_changed
455 (VCONFKEY_IDLE_LOCK_STATE,
456 _lockd_notify_lock_state_cb,
459 ("[Error] vconf notify : lock state");
464 static void lockd_start_lock_daemon(void *data)
466 struct lockd_data *lockd = NULL;
469 lockd = (struct lockd_data *)data;
475 LOCKD_DBG("%s, %d", __func__, __LINE__);
477 lockd_init_vconf(lockd);
479 r = lockd_init_sock();
481 LOCKD_DBG("lockd init socket failed: %d", r);
484 LOCKD_DBG("%s, %d", __func__, __LINE__);
487 int start_lock_daemon()
489 struct lockd_data *lockd = NULL;
492 LOCKD_DBG("%s, %d", __func__, __LINE__);
494 lockd = (struct lockd_data *)malloc(sizeof(struct lockd_data));
495 memset(lockd, 0x0, sizeof(struct lockd_data));
496 lockd_start_lock_daemon(lockd);
498 vconf_get_bool(VCONFKEY_SETAPPL_STATE_POWER_ON_LOCK_BOOL, &val);
499 LOCKD_DBG("%s, %d, val = %d", __func__, __LINE__, val);
502 lockd_launch_app_lockscreen(lockd);