change system header file from dd-system to dd-deviced
[platform/core/system/system-server.git] / src / core / predefine.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
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 #include <unistd.h>
19 #include <time.h>
20 #include <limits.h>
21 #include <fcntl.h>
22 #include <dirent.h>
23 #include <vconf.h>
24 #include <ITapiModem.h>
25 #include <TelPower.h>
26 #include <tapi_event.h>
27 #include <tapi_common.h>
28 #include <syspopup_caller.h>
29 #include <sys/reboot.h>
30 #include <sys/time.h>
31 #include <mntent.h>
32 #include <sys/mount.h>
33 #include "dd-deviced.h"
34 #include "log.h"
35 #include "launch.h"
36 #include "queue.h"
37 #include "device-node.h"
38 #include "predefine.h"
39 #include "proc/procmgr.h"
40 #include "vibrator/vibrator.h"
41 #include "core/data.h"
42 #include "common.h"
43 #include "display/poll.h"
44 #include "led/led.h"
45
46 #define CALL_EXEC_PATH                  PREFIX"/bin/call"
47 #define LOWMEM_EXEC_PATH                PREFIX"/bin/lowmem-popup"
48 #define LOWBAT_EXEC_PATH                PREFIX"/bin/lowbatt-popup"
49 #define USBCON_EXEC_PATH                PREFIX"/bin/usb-server"
50 #define TVOUT_EXEC_PATH                 PREFIX"/bin/tvout-selector"
51 #define PWROFF_EXEC_PATH                PREFIX"/bin/poweroff-popup"
52 #define MEMPS_EXEC_PATH                 PREFIX"/bin/memps"
53 #define HDMI_NOTI_EXEC_PATH             PREFIX"/bin/hdmi_connection_noti"
54 #define LOWBAT_POPUP_NAME               "lowbat-syspopup"
55 #define POWEROFF_POPUP_NAME             "poweroff-syspopup"
56 #define HDMI_POPUP_NAME                 "hdmi-syspopup"
57 #define LOWMEM_POPUP_NAME               "lowmem-syspopup"
58
59 /* wait for 5 sec as victim process be dead */
60 #define WAITING_INTERVAL                5
61
62 #define TVOUT_X_BIN                     "/usr/bin/xberc"
63 #define TVOUT_FLAG                      0x00000001
64 #define MEMPS_LOG_FILE                  "/var/log/memps"
65 #define MAX_RETRY                       2
66
67 #define POWEROFF_DURATION               2
68 #define POWEROFF_ANIMATION_PATH         "/usr/bin/boot-animation"
69 #define POWEROFF_NOTI_NAME              "power_off_start"
70
71 #define WM_READY_PATH                   "/tmp/.wm_ready"
72
73 #define LOWBAT_OPT_WARNING              1
74 #define LOWBAT_OPT_POWEROFF             2
75 #define LOWBAT_OPT_CHARGEERR            3
76 #define LOWBAT_OPT_CHECK                4
77
78 static Ecore_Timer *lowbat_popup_id = NULL;
79 static int lowbat_popup_option = 0;
80
81 static struct timeval tv_start_poweroff;
82 static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
83 static void poweroff_control_cb(keynode_t *in_key, struct ss_main_data *ad);
84 int internal_poweroff_def_predefine_action(int argc, char **argv);
85
86 static int ss_flags = 0;
87
88 static Ecore_Timer *poweroff_timer_id = NULL;
89 static TapiHandle *tapi_handle = NULL;
90 static int power_off = 0;
91
92 static int __predefine_get_pid(const char *execpath)
93 {
94         DIR *dp;
95         struct dirent *dentry;
96         int pid = -1, fd;
97         char buf[PATH_MAX];
98         char buf2[PATH_MAX];
99
100         dp = opendir("/proc");
101         if (!dp) {
102                 _E("open /proc");
103                 return -1;
104         }
105
106         while ((dentry = readdir(dp)) != NULL) {
107                 if (!isdigit(dentry->d_name[0]))
108                         continue;
109
110                 pid = atoi(dentry->d_name);
111
112                 snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
113                 fd = open(buf, O_RDONLY);
114                 if (fd < 0)
115                         continue;
116                 if (read(fd, buf2, PATH_MAX) < 0) {
117                         close(fd);
118                         continue;
119                 }
120                 close(fd);
121
122                 if (!strcmp(buf2, execpath)) {
123                         closedir(dp);
124                         return pid;
125                 }
126         }
127
128         errno = ESRCH;
129         closedir(dp);
130         return -1;
131 }
132
133 int is_power_off(void)
134 {
135         return power_off;
136 }
137
138 static void make_memps_log(char *file, pid_t pid, char *victim_name)
139 {
140         time_t now;
141         struct tm *cur_tm;
142         char params[4096];
143         char new_log[NAME_MAX];
144         static pid_t old_pid = 0;
145         int ret=-1;
146
147         if (old_pid == pid)
148                 return;
149         old_pid = pid;
150
151         now = time(NULL);
152         cur_tm = (struct tm *)malloc(sizeof(struct tm));
153         if (cur_tm == NULL) {
154                 _E("Fail to memory allocation");
155                 return;
156         }
157
158         if (localtime_r(&now, cur_tm) == NULL) {
159                 _E("Fail to get localtime");
160                 free(cur_tm);
161                 return;
162         }
163
164         _D("%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
165                  pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
166                  cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
167                  cur_tm->tm_sec);
168         snprintf(new_log, sizeof(new_log),
169                  "%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
170                  pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
171                  cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
172                  cur_tm->tm_sec);
173
174         snprintf(params, sizeof(params), "-f %s", new_log);
175         ret = ss_launch_evenif_exist(MEMPS_EXEC_PATH, params);
176         /* will be removed, just for debugging */
177         if(ret > 0) {
178                 FILE *fp;
179                 fp = open_proc_oom_adj_file(ret, "w");
180                 if (fp != NULL) {
181                         fprintf(fp, "%d", (-17));
182                         fclose(fp);
183                 }
184         }
185         free(cur_tm);
186 }
187
188 static void remount_ro()
189 {
190         struct mntent* mnt;
191         const char* table = "/etc/mtab";
192         const char mmtpoint[10][64];
193         FILE* fp;
194         int r = -1, foundmount=0;
195         char buf[256];
196         fp = setmntent(table, "r");
197
198         if (!fp)
199                 return;
200
201         while (mnt=getmntent(fp)) {
202                 if (foundmount >= 10)
203                         continue;
204                 if (!strcmp(mnt->mnt_type, "ext4") && strstr(mnt->mnt_opts, "rw")) {
205                         memset(mmtpoint[foundmount], 0, 64);
206                         strncpy(mmtpoint[foundmount], mnt->mnt_dir, 63);
207                         foundmount++;
208                 }
209         }
210         endmntent(fp);
211         while (foundmount) {
212                 foundmount--;
213                 snprintf(buf, sizeof(buf), "fuser -c %s -k -15", mmtpoint[foundmount]);
214                 sleep(1);
215                 umount2(mmtpoint[foundmount], MNT_DETACH);
216         }
217 }
218
219 static int lowmem_get_victim_pid()
220 {
221         pid_t pid;
222         int fd;
223
224         if (device_get_property(DEVICE_TYPE_MEMORY, PROP_MEMORY_VICTIM_TASK, &pid) < 0) {
225                 _E("Get victim task failed");
226                 return -1;
227         }
228
229         return pid;
230 }
231
232 int lowmem_def_predefine_action(int argc, char **argv)
233 {
234         int pid, ret, oom_adj;
235         char appname[PATH_MAX];
236
237         if (argc < 1)
238                 return -1;
239
240         if (!strcmp(argv[0], OOM_MEM_ACT)) {
241                 pid = lowmem_get_victim_pid();
242                 if (pid > 0 && pid != get_exec_pid(LOWMEM_EXEC_PATH) && pid != get_exec_pid(MEMPS_EXEC_PATH)) {
243                         if ((get_cmdline_name(pid, appname, PATH_MAX)) ==
244                             0) {
245                                 _I
246                                     ("we will kill, lowmem lv2 = %d (%s)\n",
247                                      pid, appname);
248         
249                                 make_memps_log(MEMPS_LOG_FILE, pid, appname);
250
251                                 if(get_app_oomadj(pid, &oom_adj) < 0) {
252                                         _E("Failed to get oom_adj");
253                                         return -1;
254                                 }
255                                 _D("%d will be killed with %d oom_adj value", pid, oom_adj);
256
257                                 kill(pid, SIGTERM);
258
259                                 if (oom_adj != OOMADJ_FOREGRD_LOCKED && oom_adj != OOMADJ_FOREGRD_UNLOCKED) {
260                                         return 0;
261                                 }
262
263                                 bundle *b = NULL;
264
265                                 b = bundle_create();
266                                 bundle_add(b, "_APP_NAME_", appname);
267                                 ret = syspopup_launch("lowmem-syspopup", b);
268                                 bundle_free(b);
269                                 if (ret < 0) {
270                                         _I("popup lauch failed\n");
271                                         return -1;
272                                 }
273                                 
274                                 if (set_app_oomadj(ret, OOMADJ_SU) < 0) {       
275                                         _E("Failed to set oom_adj");
276                                 }
277                         }
278                 }
279         }
280         return 0;
281 }
282
283 int usbcon_def_predefine_action(int argc, char **argv)
284 {
285         int pid;
286         int val = -1;
287         int ret = -1;
288         int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
289
290         if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val) == 0) {
291                 if (val == 0) {
292                         vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
293                                       VCONFKEY_SYSMAN_USB_DISCONNECTED);
294                         pm_unlock_internal(getpid(), LCD_OFF, STAY_CUR_STATE);
295                         return 0;
296                 }
297
298                 if ( vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &val) == 0 && val == VCONFKEY_SYSMAN_USB_AVAILABLE)
299                         return 0;
300
301                 vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
302                               VCONFKEY_SYSMAN_USB_AVAILABLE);
303                 pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
304                 pid = ss_launch_if_noexist(USBCON_EXEC_PATH, NULL);
305                 if (pid < 0) {
306                         _E("usb predefine action failed\n");
307                         return -1;
308                 }
309                 return pid;
310         }
311         _E("failed to get usb status\n");
312         return -1;
313 }
314
315 int earjackcon_def_predefine_action(int argc, char **argv)
316 {
317         int val;
318
319         _I("earjack_normal predefine action\n");
320         if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val) == 0) {
321                 return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
322         }
323
324         return -1;
325 }
326
327 int lowbat_popup(void *data)
328 {
329         int ret = -1, state = 0;
330         ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
331         if (state == 1 || ret != 0) {
332                 bundle *b = NULL;
333                 b = bundle_create();
334                 if (lowbat_popup_option == LOWBAT_OPT_WARNING || lowbat_popup_option == LOWBAT_OPT_CHECK) {
335                         bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
336                 } else if(lowbat_popup_option == LOWBAT_OPT_POWEROFF) {
337                         bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
338                 } else if(lowbat_popup_option == LOWBAT_OPT_CHARGEERR) {
339                         bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
340                 } else {
341                         bundle_add(b, "_SYSPOPUP_CONTENT_", "check");
342                 }
343
344                 ret = syspopup_launch("lowbat-syspopup", b);
345                 if (ret < 0) {
346                         _I("popup lauch failed\n");
347                         bundle_free(b);
348                         return 1;
349                 }
350                 lowbat_popup_id = NULL;
351                 lowbat_popup_option = 0;
352                 bundle_free(b);
353         } else {
354                 _I("boot-animation running yet");
355                 return 1;
356         }
357
358         return 0;
359 }
360
361
362 int predefine_control_launch(char *name, bundle *b)
363 {
364         int pid;
365         static int launched_poweroff = 0;
366         //lowbat-popup
367         if (strncmp(name, LOWBAT_POPUP_NAME, strlen(LOWBAT_POPUP_NAME)) == 0) {
368                 if (launched_poweroff == 1) {
369                         _E("will be foreced power off");
370                         internal_poweroff_def_predefine_action(0,NULL);
371                         return 0;
372                 }
373
374                 if (lowbat_popup_option == LOWBAT_OPT_POWEROFF)
375                         launched_poweroff = 1;
376
377                 pid = __predefine_get_pid(LOWBAT_EXEC_PATH);
378                 if (pid > 0) {
379                         _E("pre launched %s destroy", LOWBAT_EXEC_PATH);
380                         kill(pid, SIGTERM);
381                 }
382                 if (syspopup_launch(name, b) < 0)
383                         return -1;
384         }
385         //poweroff-popup
386         if (strncmp(name, POWEROFF_POPUP_NAME, strlen(POWEROFF_POPUP_NAME)) == 0) {
387                 if (syspopup_launch(name, b) < 0)
388                         return -1;
389         }
390         //hdmi-popup
391         if (strncmp(name, HDMI_POPUP_NAME, strlen(HDMI_POPUP_NAME)) == 0) {
392                 if (syspopup_launch(name, b) < 0)
393                         return -1;
394         }
395         //hdmi-noti
396         if (strncmp(name, HDMI_NOTI_EXEC_PATH, strlen(HDMI_NOTI_EXEC_PATH)) == 0) {
397                 if (ss_launch_if_noexist(name, "1") < 0)
398                         return -1;
399         }
400         //user mem lowmem-popup
401         if (strncmp(name, LOWMEM_POPUP_NAME, strlen(LOWMEM_POPUP_NAME)) == 0) {
402                 if (syspopup_launch(name, b) < 0)
403                         return -1;
404         }
405         return 0;
406 }
407
408 void predefine_pm_change_state(unsigned int s_bits)
409 {
410         pm_change_internal(getpid(), s_bits);
411 }
412
413 int lowbat_def_predefine_action(int argc, char **argv)
414 {
415         int ret, state=0;
416         char argstr[128];
417         char* option = NULL;
418
419         if (argc < 1)
420                 return -1;
421
422         if (lowbat_popup_id != NULL) {
423                 ecore_timer_del(lowbat_popup_id);
424                 lowbat_popup_id = NULL;
425         }
426
427         bundle *b = NULL;
428         b = bundle_create();
429         if (!strcmp(argv[0],CRITICAL_LOW_BAT_ACT)) {
430                 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
431                 lowbat_popup_option = LOWBAT_OPT_CHECK;
432         } else if(!strcmp(argv[0],WARNING_LOW_BAT_ACT)) {
433                 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
434                 lowbat_popup_option = LOWBAT_OPT_WARNING;
435         } else if(!strcmp(argv[0],POWER_OFF_BAT_ACT)) {
436                 bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
437                 lowbat_popup_option = LOWBAT_OPT_POWEROFF;
438         } else if(!strcmp(argv[0],CHARGE_ERROR_ACT)) {
439                 bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
440                 lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
441         }
442
443         ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
444         if (state == 1 || ret != 0) {
445                 if (predefine_control_launch("lowbat-syspopup", b) < 0) {
446                                 _E("popup lauch failed\n");
447                                 bundle_free(b);
448                                 lowbat_popup_option = 0;
449                                 return -1;
450                 }
451         } else {
452                 _I("boot-animation running yet");
453                 lowbat_popup_id = ecore_timer_add(1, lowbat_popup, NULL);
454         }
455         bundle_free(b);
456         return 0;
457 }
458
459 Eina_Bool powerdown_ap_by_force(void *data)
460 {
461         struct timeval now;
462         int poweroff_duration = POWEROFF_DURATION;
463         char *buf;
464
465         if(tapi_handle != NULL)
466         {
467                 tel_deinit(tapi_handle);
468                 tapi_handle = NULL;
469         }
470         /* Getting poweroff duration */
471         buf = getenv("PWROFF_DUR");
472         if (buf != NULL && strlen(buf) < 1024)
473                 poweroff_duration = atoi(buf);
474         if (poweroff_duration < 0 || poweroff_duration > 60)
475                 poweroff_duration = POWEROFF_DURATION;
476
477         gettimeofday(&now, NULL);
478         /* Waiting until power off duration and displaying animation */
479         while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
480                 usleep(100000);
481                 gettimeofday(&now, NULL);
482         }
483
484         _D("Power off by force\n");
485         /* give a chance to be terminated for each process */
486         power_off = 1;
487         sync();
488         remount_ro();
489         reboot(RB_POWER_OFF);
490         return EINA_TRUE;
491 }
492
493 static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
494 {
495         struct timeval now;
496         int poweroff_duration = POWEROFF_DURATION;
497         char *buf;
498
499         if (poweroff_timer_id) {
500                 ecore_timer_del(poweroff_timer_id);
501                 poweroff_timer_id = NULL;
502         }
503         if (tapi_handle) {
504                 tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
505                 tel_deinit(tapi_handle);
506                 tapi_handle = NULL;
507         }
508         _D("Power off \n");
509
510         /* Getting poweroff duration */
511         buf = getenv("PWROFF_DUR");
512         if (buf != NULL && strlen(buf) < 1024)
513                 poweroff_duration = atoi(buf);
514         if (poweroff_duration < 0 || poweroff_duration > 60)
515                 poweroff_duration = POWEROFF_DURATION;
516
517         gettimeofday(&now, NULL);
518         /* Waiting until power off duration and displaying animation */
519         while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
520                 usleep(100000);
521                 gettimeofday(&now, NULL);
522         }
523
524         /* give a chance to be terminated for each process */
525         power_off = 1;
526         sync();
527         remount_ro();
528         reboot(RB_POWER_OFF);
529 }
530 static void powerdown_res_cb(TapiHandle *handle, int result, void *data, void *user_data)
531 {
532         _D("poweroff command request : %d",result);
533 }
534
535 int poweroff_def_predefine_action(int argc, char **argv)
536 {
537         int retry_count = 0;
538
539         heynoti_publish(POWEROFF_NOTI_NAME);
540
541         while (retry_count < MAX_RETRY) {
542                 if (ss_action_entry_call_internal(PREDEF_INTERNAL_POWEROFF, 0) < 0) {
543                         _E("failed to request poweroff to system_server \n");
544                         retry_count++;
545                         continue;
546                 }
547                 vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
548                 return 0;
549         }
550         return -1;
551 }
552
553 int internal_poweroff_def_predefine_action(int argc, char **argv)
554 {
555         int ret;
556
557         system( LIBPATH"/system-server/shutdown.sh &");
558         sync();
559
560         gettimeofday(&tv_start_poweroff, NULL);
561         if (tapi_handle) {
562                 ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, powerdown_ap, NULL);
563
564                 if (ret != TAPI_API_SUCCESS) {
565                         _E
566                             ("tel_register_event is not subscribed. error %d\n", ret);
567                         powerdown_ap_by_force(NULL);
568                         return 0;
569                 }
570
571                 ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
572                 if (ret != TAPI_API_SUCCESS) {
573                         _E("tel_process_power_command() error %d\n", ret);
574                         powerdown_ap_by_force(NULL);
575                         return 0;
576                 }
577                 poweroff_timer_id = ecore_timer_add(15, powerdown_ap_by_force, NULL);
578         } else {
579                 powerdown_ap_by_force(NULL);
580         }
581         return 0;
582 }
583
584 static void enter_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
585 {
586         int bCurFlightMode = 0;
587         if (result != TAPI_POWER_FLIGHT_MODE_ENTER) {
588                 _E("flight mode enter failed %d",result);
589         } else {
590                 _D("enter flight mode result : %d",result);
591                 if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,&bCurFlightMode) == 0) {
592                         _D("Flight Mode is %d", bCurFlightMode);
593                 } else {
594                         _E("failed to get vconf key");
595                 }
596         }
597 }
598
599 static void leave_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
600 {
601         int bCurFlightMode = 0;
602         if (result != TAPI_POWER_FLIGHT_MODE_LEAVE) {
603                 _E("flight mode leave failed %d",result);
604         } else {
605                 _D("leave flight mode result : %d",result);
606                 if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,&bCurFlightMode) == 0) {
607                         _D("Flight Mode is %d", bCurFlightMode);
608                 } else {
609                         _E("failed to get vconf key");
610                 }
611         }
612 }
613
614 int entersleep_def_predefine_action(int argc, char **argv)
615 {
616         int ret;
617
618         pm_change_internal(getpid(), LCD_NORMAL);
619         sync();
620
621         ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER, enter_flight_mode_cb, NULL);
622         _E("request for changing into flight mode : %d\n", ret);
623
624         system("/etc/rc.d/rc.entersleep");
625         pm_change_internal(getpid(), POWER_OFF);
626
627         return 0;
628 }
629
630 int leavesleep_def_predefine_action(int argc, char **argv)
631 {
632         int ret;
633
634         pm_change_internal(getpid(), LCD_NORMAL);
635         sync();
636
637         ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE, leave_flight_mode_cb, NULL);
638         _E("request for changing into flight mode : %d\n", ret);
639
640         return 0;
641 }
642
643 static void restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
644
645 Eina_Bool restart_ap_ecore(void *data)
646 {
647         restart_ap(tapi_handle,NULL,(void *)-1,NULL);
648         return EINA_TRUE;
649 }
650
651 static void restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
652 {
653         struct timeval now;
654         int poweroff_duration = POWEROFF_DURATION;
655         char *buf;
656
657         if (poweroff_timer_id) {
658                 ecore_timer_del(poweroff_timer_id);
659                 poweroff_timer_id = NULL;
660         }
661
662
663         if(tapi_handle != NULL)
664         {
665                 tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
666                 tel_deinit(tapi_handle);
667                 tapi_handle = NULL;
668         }
669
670         _I("Restart\n");
671         vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
672         power_off = 1;
673         sync();
674
675         buf = getenv("PWROFF_DUR");
676         if (buf != NULL && strlen(buf) < 1024)
677                 poweroff_duration = atoi(buf);
678         if (poweroff_duration < 0 || poweroff_duration > 60)
679                 poweroff_duration = POWEROFF_DURATION;
680         gettimeofday(&now, NULL);
681         while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
682                 usleep(100000);
683                 gettimeofday(&now, NULL);
684         }
685         remount_ro();
686
687         reboot(RB_AUTOBOOT);
688 }
689
690 static void restart_ap_by_force(void *data)
691 {
692         struct timeval now;
693         int poweroff_duration = POWEROFF_DURATION;
694         char *buf;
695
696         if (poweroff_timer_id) {
697                 ecore_timer_del(poweroff_timer_id);
698                 poweroff_timer_id = NULL;
699         }
700
701
702         if(tapi_handle != NULL)
703         {
704                 tel_deinit(tapi_handle);
705                 tapi_handle = NULL;
706         }
707
708         _I("Restart\n");
709         power_off = 1;
710         sync();
711
712         buf = getenv("PWROFF_DUR");
713         if (buf != NULL && strlen(buf) < 1024)
714                 poweroff_duration = atoi(buf);
715         if (poweroff_duration < 0 || poweroff_duration > 60)
716                 poweroff_duration = POWEROFF_DURATION;
717         gettimeofday(&now, NULL);
718         while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
719                 usleep(100000);
720                 gettimeofday(&now, NULL);
721         }
722         remount_ro();
723
724         reboot(RB_AUTOBOOT);
725 }
726
727 int restart_def_predefine_action(int argc, char **argv)
728 {
729         int ret;
730
731         heynoti_publish(POWEROFF_NOTI_NAME);
732         pm_change_internal(getpid(), LCD_NORMAL);
733         system(LIBPATH"/system-server/shutdown.sh &");
734         sync();
735
736         gettimeofday(&tv_start_poweroff, NULL);
737
738         ret =
739             tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, restart_ap, NULL);
740         if (ret != TAPI_API_SUCCESS) {
741                 _E
742                     ("tel_register_event is not subscribed. error %d\n", ret);
743                 restart_ap_by_force((void *)-1);
744                 return 0;
745         }
746
747
748         ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
749         if (ret != TAPI_API_SUCCESS) {
750                 _E("tel_process_power_command() error %d\n", ret);
751                 restart_ap_by_force((void *)-1);
752                 return 0;
753         }
754
755         poweroff_timer_id = ecore_timer_add(15, restart_ap_ecore, NULL);
756         return 0;
757 }
758
759 int launching_predefine_action(int argc, char **argv)
760 {
761         int ret;
762
763         if (argc < 0)
764                 return -1;
765
766         /* current just launching poweroff-popup */
767         if (predefine_control_launch("poweroff-syspopup", NULL) < 0) {
768                 _E("poweroff-syspopup launch failed");
769                 return -1;
770         }
771         return 0;
772 }
773
774 int flight_mode_def_predefine_action(int argc, char **argv)
775 {
776         int bCurFlightMode;
777         int err = TAPI_API_SUCCESS;
778         if (argc != 1 || argv[0] == NULL) {
779                 _E("FlightMode Set predefine action failed");
780                 return -1;
781         }
782         bCurFlightMode = atoi(argv[0]);
783         if (bCurFlightMode == 1) {
784                 err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE, leave_flight_mode_cb, NULL);
785         } else if (bCurFlightMode == 0) {
786                 err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER, enter_flight_mode_cb, NULL);
787         }
788         if (err != TAPI_API_SUCCESS)
789                 _E("FlightMode tel api action failed %d",err);
790         return 0;
791
792 }
793
794 static void ss_action_entry_load_from_sodir()
795 {
796         DIR *dp;
797         struct dirent *dentry;
798         struct sysnoti *msg;
799         char *ext;
800         char tmp[128];
801
802         dp = opendir(PREDEFINE_SO_DIR);
803         if (!dp) {
804                 _E("fail open %s", PREDEFINE_SO_DIR);
805                 return;
806         }
807
808         msg = malloc(sizeof(struct sysnoti));
809         if (msg == NULL) {
810                 _E("Malloc failed");
811                 closedir(dp);
812                 return;
813         }
814
815         msg->pid = getpid();
816
817         while ((dentry = readdir(dp)) != NULL) {
818                 if ((ext = strstr(dentry->d_name, ".so")) == NULL)
819                         continue;
820
821                 snprintf(tmp, sizeof(tmp), "%s/%s", PREDEFINE_SO_DIR,
822                          dentry->d_name);
823                 msg->path = tmp;
824                 *ext = 0;
825                 msg->type = &(dentry->d_name[3]);
826                 ss_action_entry_add(msg);
827         }
828         free(msg);
829
830         closedir(dp);
831 }
832 static void __tel_init_cb(keynode_t *key_nodes,void *data)
833 {
834         int bTelReady = 0;
835         bTelReady = vconf_keynode_get_bool(key_nodes);
836         if (bTelReady == 1) {
837                 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, (void*)__tel_init_cb);
838                 tapi_handle = tel_init(NULL);
839                 if (tapi_handle == NULL) {
840                         _E("tapi init error");
841                 }
842         } else {
843                 _E("tapi is not ready yet");
844         }
845 }
846 static void poweroff_control_cb(keynode_t *in_key, struct ss_main_data *ad)
847 {
848         int val;
849         if (vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val) != 0)
850                 return;
851         switch (val) {
852         case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
853                 ss_action_entry_call_internal(PREDEF_POWEROFF, 0);
854                 break;
855         case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
856                 ss_action_entry_call_internal(PREDEF_PWROFF_POPUP, 0);
857                 break;
858         case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
859                 ss_action_entry_call_internal(PREDEF_REBOOT, 0);
860                 break;
861         }
862 }
863
864 void ss_predefine_internal_init(void)
865 {
866
867         /* telephony initialize */
868         int ret = 0;
869         int bTelReady = 0;
870         if (vconf_get_bool(VCONFKEY_TELEPHONY_READY,&bTelReady) == 0) {
871                 if (bTelReady == 1) {
872                         tapi_handle = tel_init(NULL);
873                         if (tapi_handle == NULL) {
874                                 _E("tapi init error");
875                         }
876                 } else {
877                         vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY, (void *)__tel_init_cb, NULL);
878                 }
879         } else {
880                 _E("failed to get tapi vconf key");
881         }
882 #ifdef NOUSE
883         ss_action_entry_add_internal(PREDEF_CALL, call_predefine_action, NULL,
884                                      NULL);
885 #endif
886         ss_action_entry_add_internal(PREDEF_LOWMEM, lowmem_def_predefine_action,
887                                      NULL, NULL);
888         ss_action_entry_add_internal(PREDEF_LOWBAT, lowbat_def_predefine_action,
889                                      NULL, NULL);
890         ss_action_entry_add_internal(PREDEF_USBCON, usbcon_def_predefine_action,
891                                      NULL, NULL);
892         ss_action_entry_add_internal(PREDEF_EARJACKCON,
893                                      earjackcon_def_predefine_action, NULL,
894                                      NULL);
895         ss_action_entry_add_internal(PREDEF_POWEROFF,
896                                      poweroff_def_predefine_action, NULL, NULL);
897         ss_action_entry_add_internal(PREDEF_PWROFF_POPUP,
898                                      launching_predefine_action, NULL, NULL);
899         ss_action_entry_add_internal(PREDEF_REBOOT,
900                                      restart_def_predefine_action, NULL, NULL);
901         ss_action_entry_add_internal(PREDEF_FLIGHT_MODE,
902                                      flight_mode_def_predefine_action, NULL, NULL);
903         ss_action_entry_add_internal(PREDEF_INTERNAL_POWEROFF,
904                                      internal_poweroff_def_predefine_action, NULL, NULL);
905         ss_action_entry_add_internal(PREDEF_HAPTIC, haptic_def_predefine_action,
906                                         NULL, NULL);
907
908         ss_action_entry_add_internal(PREDEF_LED,
909                                         led_def_predefine_action, NULL, NULL);
910
911         if (vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void *)poweroff_control_cb, NULL) < 0) {
912                 _E("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_SYSMAN_POWER_OFF_STATUS);
913         }
914         ss_action_entry_load_from_sodir();
915
916         /* check and set earjack init status */
917         earjackcon_def_predefine_action(0, NULL);
918 }