Code sync
[apps/native/starter.git] / src / lock-daemon.c
1  /*
2   * Copyright 2012  Samsung Electronics Co., Ltd
3   *
4   * Licensed under the Flora License, Version 1.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *     http://www.tizenopensource.org/license
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16
17
18
19 #include <Elementary.h>
20
21 #include <vconf.h>
22 #include <vconf-keys.h>
23
24 #include <glib.h>
25 #include <poll.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <sys/socket.h>
29 #include <sys/un.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <sys/param.h>
36 #include <errno.h>
37
38 #include "lockd-debug.h"
39 #include "lock-daemon.h"
40 #include "lockd-process-mgr.h"
41 #include "lockd-window-mgr.h"
42 #include "starter-util.h"
43 #include "menu_daemon.h"
44
45 static int phone_lock_pid;
46
47 struct lockd_data {
48         int lock_app_pid;
49         int phone_lock_app_pid;
50         int lock_type;  /* 0:Normal, 1:Security,  2:Other */
51         Eina_Bool request_recovery;
52         lockw_data *lockw;
53         GPollFD *gpollfd;
54 };
55
56 /* define it temp */
57 #if 0
58 struct ucred {
59         pid_t pid;              /* PID of sending process.  */
60         uid_t uid;              /* UID of sending process.  */
61         gid_t gid;              /* GID of sending process.  */
62 };
63 #endif
64
65 #define PHLOCK_SOCK_PREFIX "/tmp/phlock"
66 #define PHLOCK_SOCK_MAXBUFF 65535
67 #define PHLOCK_APP_CMDLINE "/usr/apps/org.tizen.phone-lock/bin/phone-lock"
68 #define MDM_APP_CMDLINE "/usr/bin/mdm-server"
69 #define PHLOCK_UNLOCK_CMD "unlock"
70 #define PHLOCK_LAUNCH_CMD "launch_phone_lock"
71 #define LAUNCH_INTERVAL 100*1000
72
73 static int lockd_launch_app_lockscreen(struct lockd_data *lockd);
74
75 static void lockd_unlock_lockscreen(struct lockd_data *lockd);
76
77 static int _lockd_get_lock_type(void)
78 {
79         int lock_type = 0;
80         int ret = 0;
81
82         vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &lock_type);
83
84         if (lock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD ||
85                 lock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD ||
86                 lock_type == SETTING_SCREEN_LOCK_TYPE_FACE_AND_VOICE) {
87                 ret = 1;
88         } else if (lock_type == SETTING_SCREEN_LOCK_TYPE_SWIPE ||
89                 lock_type == SETTING_SCREEN_LOCK_TYPE_MOTION) {
90                 ret = 0;
91         } else {
92                 ret = 2;
93         }
94
95         LOCKD_DBG("_lockd_get_lock_type ret(%d), lock_type (%d)", ret, lock_type);
96
97         return ret;
98 }
99
100 static void _lockd_notify_pm_state_cb(keynode_t * node, void *data)
101 {
102         LOCKD_DBG("PM state Notification!!");
103
104         struct lockd_data *lockd = (struct lockd_data *)data;
105         int val = -1;
106
107         if (lockd == NULL) {
108                 LOCKD_ERR("lockd is NULL");
109                 return;
110         }
111
112         if (vconf_get_int(VCONFKEY_PM_STATE, &val) < 0) {
113                 LOCKD_ERR("Cannot get VCONFKEY_PM_STATE");
114                 return;
115         }
116
117         if (val == VCONFKEY_PM_STATE_LCDOFF) {
118                 lockd->lock_type = _lockd_get_lock_type();
119                 lockd_launch_app_lockscreen(lockd);
120         }
121 }
122
123 static void
124 _lockd_notify_lock_state_cb(keynode_t * node, void *data)
125 {
126         LOCKD_DBG("lock state changed!!");
127
128         struct lockd_data *lockd = (struct lockd_data *)data;
129         int val = -1;
130
131         if (lockd == NULL) {
132                 LOCKD_ERR("lockd is NULL");
133                 return;
134         }
135
136         if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) {
137                 LOCKD_ERR("Cannot get VCONFKEY_IDLE_LOCK_STATE");
138                 return;
139         }
140
141         if (val == VCONFKEY_IDLE_UNLOCK) {
142                 LOCKD_DBG("unlocked..!!");
143                 if (lockd->lock_app_pid != 0) {
144                         LOCKD_DBG("terminate lock app..!!");
145                         lockd_process_mgr_terminate_lock_app(lockd->lock_app_pid, 1);
146                 }
147         }
148 }
149
150 static void
151 _lockd_notify_phone_lock_verification_cb(keynode_t * node, void *data)
152 {
153         LOCKD_DBG("%s, %d", __func__, __LINE__);
154
155         struct lockd_data *lockd = (struct lockd_data *)data;
156         int val = -1;
157
158         if (lockd == NULL) {
159                 LOCKD_ERR("lockd is NULL");
160                 return;
161         }
162
163         if (vconf_get_bool(VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION, &val) < 0) {
164                 LOCKD_ERR("Cannot get %s", VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION);
165                 return;
166         }
167
168         if (val == TRUE) {
169                 /* password verified */
170                 /* lockd_unlock_lockscreen(lockd); */
171                 lockd_window_mgr_finish_lock(lockd->lockw);
172                 vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
173         }
174 }
175
176 static int lockd_app_dead_cb(int pid, void *data)
177 {
178         LOCKD_DBG("app dead cb call! (pid : %d)", pid);
179
180         struct lockd_data *lockd = (struct lockd_data *)data;
181
182         if (pid == lockd->lock_app_pid && lockd->lock_type == 0) {
183                 LOCKD_DBG("lock app(pid:%d) is destroyed.", pid);
184
185                 lockd_unlock_lockscreen(lockd);
186         }
187
188         menu_daemon_check_dead_signal(pid);
189
190         return 0;
191 }
192
193 static Eina_Bool lockd_set_lock_state_cb(void *data)
194 {
195         LOCKD_DBG("%s, %d", __func__, __LINE__);
196         vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_LOCK);
197         return ECORE_CALLBACK_CANCEL;
198 }
199
200 static Eina_Bool lockd_app_create_cb(void *data, int type, void *event)
201 {
202         struct lockd_data *lockd = (struct lockd_data *)data;
203
204         if (lockd == NULL) {
205                 return ECORE_CALLBACK_PASS_ON;
206         }
207         LOCKD_DBG("%s, %d", __func__, __LINE__);
208         lockd_window_set_window_effect(lockd->lockw, lockd->lock_app_pid,
209                                        event);
210         //FIXME sometimes show cb is not called.
211         lockd_window_set_window_property(lockd->lockw, lockd->lock_app_pid,
212                                          event);
213
214         return ECORE_CALLBACK_PASS_ON;
215 }
216
217 static Eina_Bool lockd_app_show_cb(void *data, int type, void *event)
218 {
219         struct lockd_data *lockd = (struct lockd_data *)data;
220
221         if (lockd == NULL) {
222                 return EINA_TRUE;
223         }
224         LOCKD_DBG("%s, %d", __func__, __LINE__);
225         lockd_window_set_window_property(lockd->lockw, lockd->lock_app_pid,
226                                          event);
227         if (lockd->lock_type > 1)
228                 ecore_idler_add(lockd_set_lock_state_cb, NULL);
229
230         return EINA_FALSE;
231 }
232
233 static int lockd_launch_app_lockscreen(struct lockd_data *lockd)
234 {
235         LOCKD_DBG("launch app lock screen");
236
237         int call_state = -1, phlock_state = -1, factory_mode = -1, test_mode = -1;
238         int r = 0;
239
240         WRITE_FILE_LOG("%s", "Launch lockscreen in starter");
241         vconf_get_int(VCONFKEY_TELEPHONY_SIM_FACTORY_MODE, &factory_mode);
242         if (factory_mode == VCONFKEY_TELEPHONY_SIM_FACTORYMODE_ON) {
243                 LOCKD_DBG("Factory mode ON, lock screen can't be launched..!!");
244                 return 0;
245         }
246         vconf_get_int(VCONFKEY_TESTMODE_SCREEN_LOCK, &test_mode);
247         if (test_mode == VCONFKEY_TESTMODE_SCREEN_LOCK_DISABLE) {
248                 LOCKD_DBG("Test mode ON, lock screen can't be launched..!!");
249                 return 0;
250         }
251
252         /* Check lock screen application is already exit, no checking phone-lock */
253         if (lockd_process_mgr_check_lock(lockd->lock_app_pid) == TRUE) {
254                 LOCKD_DBG("Lock Screen App is already running.");
255                 r = lockd_process_mgr_restart_lock(lockd->lock_type);
256                 if (r < 0) {
257                         LOCKD_DBG("Restarting Lock Screen App is fail [%d].", r);
258                         usleep(LAUNCH_INTERVAL);
259                 } else {
260                         LOCKD_DBG("Restarting Lock Screen App, pid[%d].", r);
261                         return 1;
262                 }
263         }
264
265         /* Get Call state */
266         vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
267         if (call_state != VCONFKEY_CALL_OFF) {
268                 LOCKD_DBG
269                     ("Current call state(%d) does not allow to launch lock screen.",
270                      call_state);
271                 return 0;
272         }
273
274         if (lockd->lock_type == 0) {
275                 lockd->lock_app_pid =
276                     lockd_process_mgr_start_normal_lock(lockd, lockd_app_dead_cb);
277                 if (lockd->lock_app_pid < 0)
278                         return 0;
279                 /* reset window mgr before start win mgr  */
280                 lockd_window_mgr_finish_lock(lockd->lockw);
281                 lockd_window_mgr_ready_lock(lockd, lockd->lockw, lockd_app_create_cb,
282                                             lockd_app_show_cb);
283         } else if (lockd->lock_type == 1) {
284                 vconf_set_bool(VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION, FALSE);
285                 /* Check phone lock application is already exit */
286                 if (lockd_process_mgr_check_lock(lockd->phone_lock_app_pid) == TRUE) {
287                         LOCKD_DBG("phone lock App is already running.");
288                         if (lockd->request_recovery == FALSE)
289                                 return 1;
290                 }
291
292                 /* TO DO : Recovery should be checked by EAS interface later */
293                 /* After getting EAS interface, we should remove lockd->request_recovery */
294                 if (lockd->request_recovery == TRUE) {
295                         lockd->phone_lock_app_pid =
296                             lockd_process_mgr_start_recovery_lock();
297                         lockd->request_recovery = FALSE;
298                 } else {
299                         lockd->phone_lock_app_pid =
300                             lockd_process_mgr_start_phone_lock();
301                 }
302                 phone_lock_pid = lockd->phone_lock_app_pid;
303                 LOCKD_DBG("%s, %d, phone_lock_pid = %d", __func__, __LINE__,
304                           phone_lock_pid);
305                 lockd_window_set_phonelock_pid(lockd->lockw, phone_lock_pid);
306
307                 /* Set lock state */ 
308                 //ecore_idler_add(lockd_set_lock_state_cb, NULL); //don't set lock state for lcd on.
309         } else {
310                 lockd->lock_app_pid =
311                     lockd_process_mgr_start_lock(lockd, lockd_app_dead_cb,
312                                                  lockd->lock_type);
313                 if (lockd->lock_app_pid < 0)
314                         return 0;
315                 /* reset window mgr before start win mgr  */
316                 lockd_window_mgr_finish_lock(lockd->lockw);
317                 lockd_window_mgr_ready_lock(lockd, lockd->lockw, lockd_app_create_cb,
318                                             lockd_app_show_cb);
319         }
320         return 1;
321 }
322
323 static void lockd_unlock_lockscreen(struct lockd_data *lockd)
324 {
325         LOCKD_DBG("unlock lock screen");
326         lockd->lock_app_pid = 0;
327
328         vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
329         lockd_window_mgr_finish_lock(lockd->lockw);
330 }
331
332 inline static void lockd_set_sock_option(int fd, int cli)
333 {
334         int size;
335         struct timeval tv = { 1, 200 * 1000 };  /* 1.2 sec */
336
337         size = PHLOCK_SOCK_MAXBUFF;
338         setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
339         setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
340         if (cli)
341                 setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
342 }
343
344 static int lockd_create_sock(void)
345 {
346         struct sockaddr_un saddr;
347         int fd;
348
349         fd = socket(AF_UNIX, SOCK_STREAM, 0);   /* support above version 2.6.27 */
350         if (fd < 0) {
351                 if (errno == EINVAL) {
352                         fd = socket(AF_UNIX, SOCK_STREAM, 0);
353                         if (fd < 0) {
354                                 LOCKD_DBG
355                                     ("second chance - socket create error");
356                                 return -1;
357                         }
358                 } else {
359                         LOCKD_DBG("socket error");
360                         return -1;
361                 }
362         }
363
364         bzero(&saddr, sizeof(saddr));
365         saddr.sun_family = AF_UNIX;
366
367         strncpy(saddr.sun_path, PHLOCK_SOCK_PREFIX, strlen(PHLOCK_SOCK_PREFIX));
368         saddr.sun_path[strlen(PHLOCK_SOCK_PREFIX)] = 0;
369
370         unlink(saddr.sun_path);
371
372         if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
373                 LOCKD_DBG("bind error");
374                 return -1;
375         }
376
377         if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
378                 /* Flawfinder: ignore */
379                 LOCKD_DBG("failed to change the socket permission");
380                 return -1;
381         }
382
383         lockd_set_sock_option(fd, 0);
384
385         if (listen(fd, 10) == -1) {
386                 LOCKD_DBG("listen error");
387                 return -1;
388         }
389
390         return fd;
391 }
392
393 static gboolean lockd_glib_check(GSource * src)
394 {
395         GSList *fd_list;
396         GPollFD *tmp;
397
398         fd_list = src->poll_fds;
399         do {
400                 tmp = (GPollFD *) fd_list->data;
401                 if ((tmp->revents & (POLLIN | POLLPRI)))
402                         return TRUE;
403                 fd_list = fd_list->next;
404         } while (fd_list);
405
406         return FALSE;
407 }
408
409 static char *lockd_read_cmdline_from_proc(int pid)
410 {
411         int memsize = 32;
412         char path[32];
413         char *cmdline = NULL, *tempptr = NULL;
414         FILE *fp = NULL;
415
416         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
417
418         fp = fopen(path, "r");
419         if (fp == NULL) {
420                 LOCKD_DBG("Cannot open cmdline on pid[%d]", pid);
421                 return NULL;
422         }
423
424         cmdline = malloc(32);
425         if (cmdline == NULL) {
426                 LOCKD_DBG("%s", "Out of memory");
427                 fclose(fp);
428                 return NULL;
429         }
430
431         bzero(cmdline, memsize);
432         if (fgets(cmdline, 32, fp) == NULL) {
433                 LOCKD_DBG("%s", "Cannot read cmdline");
434                 free(cmdline);
435                 fclose(fp);
436                 return NULL;
437         }
438
439         while (cmdline[memsize - 2] != 0) {
440                 cmdline[memsize - 1] = (char)fgetc(fp);
441                 tempptr = realloc(cmdline, memsize + 32);
442                 if (tempptr == NULL) {
443                         fclose(fp);
444                         LOCKD_DBG("%s", "Out of memory");
445                         return NULL;
446                 }
447                 cmdline = tempptr;
448                 bzero(cmdline + memsize, 32);
449                 fgets(cmdline + memsize, 32, fp);
450                 memsize += 32;
451         }
452
453         if (fp != NULL)
454                 fclose(fp);
455         return cmdline;
456 }
457
458 static int lockd_sock_handler(void *data)
459 {
460         int cl;
461         int len;
462         int sun_size;
463         int clifd = -1;
464         char cmd[PHLOCK_SOCK_MAXBUFF];
465         char *cmdline = NULL;
466         int val = -1;
467         int fd = -1;
468         int recovery_state = -1;
469         GPollFD *gpollfd;
470
471         struct ucred cr;
472         struct sockaddr_un lockd_addr;
473         struct lockd_data *lockd = (struct lockd_data *)data;
474
475         if ((lockd == NULL) || (lockd->gpollfd == NULL)) {
476                 LOCKD_DBG("lockd->gpollfd is NULL");
477                 return -1;
478         }
479         gpollfd = (GPollFD *)lockd->gpollfd;
480         fd = gpollfd->fd;
481
482         cl = sizeof(cr);
483         sun_size = sizeof(struct sockaddr_un);
484
485         if ((clifd =
486              accept(fd, (struct sockaddr *)&lockd_addr,
487                     (socklen_t *) & sun_size)) == -1) {
488                 if (errno != EINTR)
489                         LOCKD_DBG("accept error");
490                 return -1;
491         }
492
493         if (getsockopt(clifd, SOL_SOCKET, SO_PEERCRED, &cr, (socklen_t *) & cl)
494             < 0) {
495                 LOCKD_DBG("peer information error");
496                 close(clifd);
497                 return -1;
498         }
499         LOCKD_DBG("Peer's pid=%d, uid=%d, gid=%d\n", cr.pid, cr.uid, cr.gid);
500
501         memset(cmd, 0, PHLOCK_SOCK_MAXBUFF);
502
503         lockd_set_sock_option(clifd, 1);
504
505         /* receive single packet from socket */
506         len = recv(clifd, cmd, PHLOCK_SOCK_MAXBUFF, 0);
507
508         if (cmd == NULL) {
509                 LOCKD_DBG("recv error, cmd is NULL");
510                 close(clifd);
511                 return -1;
512         }
513
514         if (len != strlen(cmd)) {
515                 LOCKD_DBG("recv error %d %d", len, strlen(cmd));
516                 close(clifd);
517                 return -1;
518         }
519
520         LOCKD_DBG("cmd %s", cmd);
521
522         /* Read command line of the PID from proc fs */
523         cmdline = lockd_read_cmdline_from_proc(cr.pid);
524         if (cmdline == NULL) {
525                 /* It's weired. no file in proc file system, */
526                 LOCKD_DBG("Error on opening /proc/%d/cmdline", cr.pid);
527                 close(clifd);
528                 return -1;
529         }
530
531         LOCKD_DBG("/proc/%d/cmdline : %s", cr.pid, cmdline);
532         LOCKD_DBG("phone_lock_pid : %d vs cr.pid : %d", phone_lock_pid, cr.pid);
533
534         if ((!strncmp(cmdline, PHLOCK_APP_CMDLINE, strlen(cmdline)))
535             && (!strncmp(cmd, PHLOCK_UNLOCK_CMD, strlen(cmd)))) {
536                 LOCKD_DBG("cmd is %s\n", PHLOCK_UNLOCK_CMD);
537
538                 if (phone_lock_pid == cr.pid) {
539                         LOCKD_DBG("pid [%d] %s is verified, unlock..!!\n", cr.pid,
540                                   cmdline);
541                         lockd_process_mgr_terminate_phone_lock(phone_lock_pid);
542                         phone_lock_pid = 0;
543                         vconf_set_bool(VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION, TRUE);
544                 }
545         } else if (!strncmp(cmd, PHLOCK_LAUNCH_CMD, strlen(cmd))) {
546                 LOCKD_DBG("cmd is %s\n", PHLOCK_LAUNCH_CMD);
547
548                 if (!strncmp(cmdline, MDM_APP_CMDLINE, strlen(cmdline))) {
549                         LOCKD_DBG("cmdline is %s \n", MDM_APP_CMDLINE);
550                         if (vconf_get_int(VCONFKEY_EAS_RECOVERY_MODE, &recovery_state) < 0) {
551                                 LOCKD_ERR("Cannot get %s vconfkey", VCONFKEY_EAS_RECOVERY_MODE);
552                                 lockd->request_recovery = FALSE;
553                         } else if (recovery_state == 1) {
554                                 LOCKD_DBG("recovery mode : %d \n", recovery_state);
555                                 lockd->request_recovery = TRUE;
556                         } else {
557                                 lockd->request_recovery = FALSE;
558                         }
559                 }
560
561                 if (_lockd_get_lock_type() == 1) {
562                         lockd->lock_type = 1;
563                         lockd_launch_app_lockscreen(lockd);
564                 }
565         }
566
567         close(clifd);
568         return 0;
569 }
570
571 static gboolean lockd_glib_handler(gpointer data)
572 {
573         if (lockd_sock_handler(data) < 0) {
574                 LOCKD_DBG("lockd_sock_handler is failed..!!");
575         }
576         return TRUE;
577 }
578
579 static gboolean lockd_glib_dispatch(GSource * src, GSourceFunc callback,
580                                     gpointer data)
581 {
582         callback(data);
583         return TRUE;
584 }
585
586 static gboolean lockd_glib_prepare(GSource * src, gint * timeout)
587 {
588         return FALSE;
589 }
590
591 static GSourceFuncs funcs = {
592         .prepare = lockd_glib_prepare,
593         .check = lockd_glib_check,
594         .dispatch = lockd_glib_dispatch,
595         .finalize = NULL
596 };
597
598 static int lockd_init_sock(struct lockd_data *lockd)
599 {
600         int fd;
601         GPollFD *gpollfd;
602         GSource *src;
603         int ret;
604
605         fd = lockd_create_sock();
606         if (fd < 0) {
607                 LOCKD_DBG("lock daemon create sock failed..!!");
608         }
609
610         src = g_source_new(&funcs, sizeof(GSource));
611
612         gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
613         gpollfd->events = POLLIN;
614         gpollfd->fd = fd;
615
616         lockd->gpollfd = gpollfd;
617
618         g_source_add_poll(src, lockd->gpollfd);
619         g_source_set_callback(src, (GSourceFunc) lockd_glib_handler,
620                               (gpointer) lockd, NULL);
621         g_source_set_priority(src, G_PRIORITY_LOW);
622
623         ret = g_source_attach(src, NULL);
624         if (ret == 0)
625                 return -1;
626
627         g_source_unref(src);
628
629         return 0;
630 }
631
632 static void lockd_init_vconf(struct lockd_data *lockd)
633 {
634         int val = -1;
635
636         if (vconf_notify_key_changed
637             (VCONFKEY_PM_STATE, _lockd_notify_pm_state_cb, lockd) != 0) {
638                 LOCKD_ERR("Fail vconf_notify_key_changed : VCONFKEY_PM_STATE");
639         }
640
641         if (vconf_notify_key_changed
642             (VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION,
643              _lockd_notify_phone_lock_verification_cb, lockd) != 0) {
644                 if (vconf_get_bool(VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION, &val) < 0) {
645                         LOCKD_ERR
646                             ("Cannot get %s", VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION);
647                         vconf_set_bool(VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION, 0);
648                         if (vconf_notify_key_changed
649                             (VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION,
650                              _lockd_notify_phone_lock_verification_cb,
651                              lockd) != 0) {
652                                 LOCKD_ERR
653                                     ("Fail vconf_notify_key_changed : %s", VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION);
654                         }
655                 } else {
656                         LOCKD_ERR
657                             ("Fail vconf_notify_key_changed : %s", VCONFKEY_LOCKSCREEN_PHONE_LOCK_VERIFICATION);
658                 }
659         }
660
661         if (vconf_notify_key_changed
662             (VCONFKEY_IDLE_LOCK_STATE,
663              _lockd_notify_lock_state_cb,
664              lockd) != 0) {
665                 LOCKD_ERR
666                     ("[Error] vconf notify : lock state");
667         }
668 }
669
670 static void lockd_start_lock_daemon(void *data)
671 {
672         struct lockd_data *lockd = NULL;
673         int r = 0;
674
675         lockd = (struct lockd_data *)data;
676
677         if (!lockd) {
678                 return;
679         }
680
681         LOCKD_DBG("%s, %d", __func__, __LINE__);
682
683         /* register vconf notification */
684         lockd_init_vconf(lockd);
685
686         /* Initialize socket */
687         r = lockd_init_sock(lockd);
688         if (r < 0) {
689                 LOCKD_DBG("lockd init socket failed: %d", r);
690         }
691         /* Create internal 1x1 window */
692         lockd->lockw = lockd_window_init();
693
694         aul_listen_app_dead_signal(lockd_app_dead_cb, data);
695
696         LOCKD_DBG("%s, %d", __func__, __LINE__);
697 }
698
699 int start_lock_daemon(int launch_lock)
700 {
701         struct lockd_data *lockd = NULL;
702         int val = -1;
703         int recovery_state = -1;
704         int first_boot = 0;
705         int lock_type = 0;
706         int ret = 0;
707
708         LOCKD_DBG("%s, %d", __func__, __LINE__);
709
710         lockd = (struct lockd_data *)malloc(sizeof(struct lockd_data));
711         memset(lockd, 0x0, sizeof(struct lockd_data));
712         lockd_start_lock_daemon(lockd);
713
714         if (launch_lock == FALSE) {
715                 LOCKD_DBG("Don't launch lockscreen..");
716                 return 0;
717         }
718
719         if (vconf_get_bool(VCONFKEY_PWLOCK_FIRST_BOOT, &first_boot) < 0) {
720                 LOCKD_ERR("Cannot get %s vconfkey", VCONFKEY_PWLOCK_FIRST_BOOT);
721         } else if (first_boot == 1) {
722                 LOCKD_DBG("first_boot : %d \n", first_boot);
723                 return 0;
724         }
725
726         lock_type = _lockd_get_lock_type();
727         if (lock_type == 1) {
728                 if (vconf_get_int(VCONFKEY_EAS_RECOVERY_MODE, &recovery_state) < 0) {
729                         LOCKD_ERR("Cannot get %s vconfkey", VCONFKEY_EAS_RECOVERY_MODE);
730                         lockd->request_recovery = FALSE;
731                 } else if (recovery_state == 1) {
732                         LOCKD_DBG("recovery mode : %d \n", recovery_state);
733                         lockd->request_recovery = TRUE;
734                 } else {
735                         lockd->request_recovery = FALSE;
736                 }
737         } else if (lock_type == 2) {
738                 lock_type = 0;
739         }
740         lockd->lock_type = lock_type;
741         ret = lockd_launch_app_lockscreen(lockd);
742         return ret;
743 }