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