2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://www.tizenopensource.org/license
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.
26 #include <ITapiModem.h>
28 #include <tapi_event.h>
29 #include <tapi_common.h>
30 #include <syspopup_caller.h>
31 #include <sys/reboot.h>
35 #include "ss_launch.h"
37 #include "ss_device_handler.h"
38 #include "ss_device_plugin.h"
39 #include "ss_predefine.h"
40 #include "ss_procmgr.h"
41 #include "include/ss_data.h"
43 #define PREDEFINE_SO_DIR PREFIX"/lib/ss_predefine/"
45 #define CALL_EXEC_PATH PREFIX"/bin/call"
46 #define LOWMEM_EXEC_PATH PREFIX"/bin/lowmem-popup"
47 #define LOWBAT_EXEC_PATH PREFIX"/bin/lowbatt-popup"
48 #define USBCON_EXEC_PATH PREFIX"/bin/usb-server"
49 #define TVOUT_EXEC_PATH PREFIX"/bin/tvout-selector"
50 #define PWROFF_EXEC_PATH PREFIX"/bin/poweroff-popup"
51 #define MEMPS_EXEC_PATH PREFIX"/bin/memps"
53 /* wait for 5 sec as victim process be dead */
54 #define WAITING_INTERVAL 5
56 #define TVOUT_X_BIN "/usr/bin/xberc"
57 #define TVOUT_FLAG 0x00000001
58 #define MEMPS_LOG_FILE "/var/log/memps"
61 #define POWEROFF_DURATION 2
62 #define POWEROFF_ANIMATION_PATH "/usr/bin/boot-animation"
63 #define POWEROFF_NOTI_NAME "power_off_start"
65 #define WM_READY_PATH "/tmp/.wm_ready"
67 #define LOWBAT_OPT_WARNING 1
68 #define LOWBAT_OPT_POWEROFF 2
69 #define LOWBAT_OPT_CHARGEERR 3
70 #define LOWBAT_OPT_CHECK 4
72 static Ecore_Timer *lowbat_popup_id = NULL;
73 static int lowbat_popup_option = 0;
75 static struct timeval tv_start_poweroff;
76 static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
78 static int ss_flags = 0;
80 static Ecore_Timer *poweroff_timer_id = NULL;
81 static TapiHandle *tapi_handle = NULL;
83 static void make_memps_log(char *file, pid_t pid, char *victim_name)
88 char new_log[NAME_MAX];
89 static pid_t old_pid = 0;
97 cur_tm = (struct tm *)malloc(sizeof(struct tm));
99 PRT_TRACE_ERR("Fail to memory allocation");
103 if (localtime_r(&now, cur_tm) == NULL) {
104 PRT_TRACE_ERR("Fail to get localtime");
108 PRT_TRACE("%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
109 pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
110 cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
112 snprintf(new_log, sizeof(new_log),
113 "%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
114 pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
115 cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
118 snprintf(params, sizeof(params), "-f %s", new_log);
119 ret = ss_launch_evenif_exist(MEMPS_EXEC_PATH, params);
124 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", ret);
125 fp = fopen(buf, "w");
127 fprintf(fp, "%d", (-17));
134 static int lowmem_get_victim_pid()
139 if (0 > plugin_intf->OEM_sys_get_memnotify_victim_task(&pid)) {
140 PRT_TRACE_ERR("Get victim task failed");
147 int lowmem_def_predefine_action(int argc, char **argv)
149 int pid, ret, oom_adj;
150 char appname[PATH_MAX];
155 if (!strcmp(argv[0], OOM_MEM_ACT)) {
156 pid = lowmem_get_victim_pid();
157 if (pid > 0 && pid != sysman_get_pid(LOWMEM_EXEC_PATH) && pid != sysman_get_pid(MEMPS_EXEC_PATH)) {
158 if ((sysman_get_cmdline_name(pid, appname, PATH_MAX)) ==
161 ("we will kill, lowmem lv2 = %d (%s)\n",
164 make_memps_log(MEMPS_LOG_FILE, pid, appname);
166 if(get_app_oomadj(pid, &oom_adj) < 0) {
167 PRT_TRACE_ERR("Failed to get oom_adj");
169 PRT_TRACE("%d will be killed with %d oom_adj value", pid, oom_adj);
173 if (oom_adj >= OOMADJ_BACKGRD_UNLOCKED) {
180 bundle_add(b, "_APP_NAME_", appname);
181 ret = syspopup_launch("lowmem-syspopup", b);
184 PRT_TRACE_EM("popup lauch failed\n");
188 if (set_app_oomadj(ret, OOMADJ_SU) < 0) {
189 PRT_TRACE_ERR("Failed to set oom_adj");
194 PRT_TRACE_EM("making memps log for low memory\n");
195 make_memps_log(MEMPS_LOG_FILE, 1, "LOWMEM_WARNING");
201 int usbcon_def_predefine_action(int argc, char **argv)
206 int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
208 if (plugin_intf->OEM_sys_get_jack_usb_online(&val) == 0) {
210 vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
211 VCONFKEY_SYSMAN_USB_DISCONNECTED);
212 pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
214 vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
215 if(bat_state < VCONFKEY_SYSMAN_BAT_NORMAL) {
218 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
220 ret = syspopup_launch("lowbat-syspopup", b);
222 PRT_TRACE_EM("popup lauch failed\n");
229 vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
230 VCONFKEY_SYSMAN_USB_AVAILABLE);
231 pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
232 pid = ss_launch_if_noexist(USBCON_EXEC_PATH, NULL);
234 PRT_TRACE_ERR("usb predefine action failed\n");
239 PRT_TRACE_ERR("failed to get usb status\n");
243 int earjackcon_def_predefine_action(int argc, char **argv)
247 PRT_TRACE_EM("earjack_normal predefine action\n");
248 if (plugin_intf->OEM_sys_get_jack_earjack_online(&val) == 0) {
249 return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
255 int lowbat_popup(void *data)
257 int ret = -1, state = 0;
258 ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
259 if (state == 1 || ret != 0) {
262 if(lowbat_popup_option == LOWBAT_OPT_WARNING) {
263 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
264 } else if(lowbat_popup_option == LOWBAT_OPT_POWEROFF) {
265 bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
266 } else if(lowbat_popup_option == LOWBAT_OPT_CHARGEERR) {
267 bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
269 bundle_add(b, "_SYSPOPUP_CONTENT_", "check");
272 ret = syspopup_launch("lowbat-syspopup", b);
274 PRT_TRACE_EM("popup lauch failed\n");
278 lowbat_popup_id = NULL;
279 lowbat_popup_option = 0;
282 PRT_TRACE_EM("boot-animation running yet");
289 int lowbat_def_predefine_action(int argc, char **argv)
298 if(lowbat_popup_id != NULL) {
299 ecore_timer_del(lowbat_popup_id);
300 lowbat_popup_id = NULL;
305 if(!strcmp(argv[0],WARNING_LOW_BAT_ACT) || !strcmp(argv[0],CRITICAL_LOW_BAT_ACT)) {
306 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
307 lowbat_popup_option = LOWBAT_OPT_WARNING;
308 } else if(!strcmp(argv[0],POWER_OFF_BAT_ACT)) {
309 bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
310 lowbat_popup_option = LOWBAT_OPT_POWEROFF;
311 } else if(!strcmp(argv[0],CHARGE_ERROR_ACT)) {
312 bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
313 lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
315 bundle_add(b, "_SYSPOPUP_CONTENT_", "check");
316 lowbat_popup_option = LOWBAT_OPT_CHECK;
319 ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
320 if (state == 1 || ret != 0) {
321 ret = syspopup_launch("lowbat-syspopup", b);
323 PRT_TRACE_EM("popup lauch failed\n");
325 lowbat_popup_option = 0;
329 PRT_TRACE_EM("boot-animation running yet");
330 lowbat_popup_id = ecore_timer_add(1, lowbat_popup, NULL);
336 Eina_Bool powerdown_ap_by_force(void *data)
339 int poweroff_duration = POWEROFF_DURATION;
342 if(tapi_handle != NULL)
344 tel_deinit(tapi_handle);
347 /* Getting poweroff duration */
348 buf = getenv("PWROFF_DUR");
349 if (buf != NULL && strlen(buf) < 1024)
350 poweroff_duration = atoi(buf);
351 if (poweroff_duration < 0 || poweroff_duration > 60)
352 poweroff_duration = POWEROFF_DURATION;
354 gettimeofday(&now, NULL);
355 /* Waiting until power off duration and displaying animation */
356 while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
358 gettimeofday(&now, NULL);
361 PRT_TRACE("Power off by force\n");
363 /* give a chance to be terminated for each process */
366 reboot(RB_POWER_OFF);
370 static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
373 int poweroff_duration = POWEROFF_DURATION;
376 if (poweroff_timer_id) {
377 ecore_timer_del(poweroff_timer_id);
378 poweroff_timer_id = NULL;
381 tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
382 tel_deinit(tapi_handle);
385 PRT_TRACE("Power off \n");
387 /* Getting poweroff duration */
388 buf = getenv("PWROFF_DUR");
389 if (buf != NULL && strlen(buf) < 1024)
390 poweroff_duration = atoi(buf);
391 if (poweroff_duration < 0 || poweroff_duration > 60)
392 poweroff_duration = POWEROFF_DURATION;
394 gettimeofday(&now, NULL);
395 /* Waiting until power off duration and displaying animation */
396 while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
398 gettimeofday(&now, NULL);
402 /* give a chance to be terminated for each process */
405 reboot(RB_POWER_OFF);
407 static void powerdown_res_cb(TapiHandle *handle, int result, void *data, void *user_data)
409 PRT_TRACE("poweroff command request : %d",result);
411 int poweroff_def_predefine_action(int argc, char **argv)
415 heynoti_publish(POWEROFF_NOTI_NAME);
417 pm_change_state(LCD_NORMAL);
418 system("/etc/rc.d/rc.shutdown &");
421 gettimeofday(&tv_start_poweroff, NULL);
422 ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, powerdown_ap, NULL);
424 if (ret != TAPI_API_SUCCESS) {
426 ("tel_register_event is not subscribed. error %d\n", ret);
427 powerdown_ap_by_force(NULL);
431 ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
432 if (ret != TAPI_API_SUCCESS) {
433 PRT_TRACE_ERR("tel_process_power_command() error %d\n", ret);
434 powerdown_ap_by_force(NULL);
438 poweroff_timer_id = ecore_timer_add(15, powerdown_ap_by_force, NULL);
442 static void enter_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
444 PRT_TRACE("enter flight mode result : %d",result);
447 static void leave_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
449 PRT_TRACE("leave flight mode result : %d",result);
452 int entersleep_def_predefine_action(int argc, char **argv)
456 pm_change_state(LCD_NORMAL);
459 ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER, enter_flight_mode_cb, NULL);
460 PRT_TRACE_ERR("request for changing into flight mode : %d\n", ret);
462 system("/etc/rc.d/rc.entersleep");
463 pm_change_state(POWER_OFF);
468 int leavesleep_def_predefine_action(int argc, char **argv)
472 pm_change_state(LCD_NORMAL);
475 ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE, leave_flight_mode_cb, NULL);
476 PRT_TRACE_ERR("request for changing into flight mode : %d\n", ret);
481 static void restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
483 Eina_Bool restart_ap_ecore(void *data)
485 restart_ap(tapi_handle,NULL,(void *)-1,NULL);
489 static void restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
492 int poweroff_duration = POWEROFF_DURATION;
495 if (poweroff_timer_id) {
496 ecore_timer_del(poweroff_timer_id);
497 poweroff_timer_id = NULL;
501 if(tapi_handle != NULL)
503 tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
504 tel_deinit(tapi_handle);
508 PRT_INFO("Restart\n");
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 gettimeofday(&now, NULL);
517 while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
519 gettimeofday(&now, NULL);
525 static void restart_ap_by_force(void *data)
528 int poweroff_duration = POWEROFF_DURATION;
531 if (poweroff_timer_id) {
532 ecore_timer_del(poweroff_timer_id);
533 poweroff_timer_id = NULL;
537 if(tapi_handle != NULL)
539 tel_deinit(tapi_handle);
543 PRT_INFO("Restart\n");
546 buf = getenv("PWROFF_DUR");
547 if (buf != NULL && strlen(buf) < 1024)
548 poweroff_duration = atoi(buf);
549 if (poweroff_duration < 0 || poweroff_duration > 60)
550 poweroff_duration = POWEROFF_DURATION;
551 gettimeofday(&now, NULL);
552 while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
554 gettimeofday(&now, NULL);
560 int restart_def_predefine_action(int argc, char **argv)
564 pm_change_state(LCD_NORMAL);
565 system("/etc/rc.d/rc.shutdown &");
568 gettimeofday(&tv_start_poweroff, NULL);
571 tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, restart_ap, NULL);
572 if (ret != TAPI_API_SUCCESS) {
574 ("tel_register_event is not subscribed. error %d\n", ret);
575 restart_ap_by_force((void *)-1);
580 ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
581 if (ret != TAPI_API_SUCCESS) {
582 PRT_TRACE_ERR("tel_process_power_command() error %d\n", ret);
583 restart_ap_by_force((void *)-1);
587 poweroff_timer_id = ecore_timer_add(15, restart_ap_ecore, NULL);
591 int launching_predefine_action(int argc, char **argv)
598 /* current just launching poweroff-popup */
599 ret = syspopup_launch("poweroff-syspopup", NULL);
601 PRT_TRACE_ERR("poweroff popup predefine action failed");
607 static void ss_action_entry_load_from_sodir()
610 struct dirent *dentry;
615 dp = opendir(PREDEFINE_SO_DIR);
617 ERR("fail open %s", PREDEFINE_SO_DIR);
621 msg = malloc(sizeof(struct sysnoti));
623 ERR("Malloc failed");
630 while ((dentry = readdir(dp)) != NULL) {
631 if ((ext = strstr(dentry->d_name, ".so")) == NULL)
634 snprintf(tmp, sizeof(tmp), "%s/%s", PREDEFINE_SO_DIR,
638 msg->type = &(dentry->d_name[3]);
639 ss_action_entry_add(msg);
646 void ss_predefine_internal_init(void)
649 /* telephony initialize */
651 tapi_handle = tel_init(NULL);
652 if (tapi_handle == NULL) {
653 PRT_TRACE_ERR("tapi init error");
656 ss_action_entry_add_internal(PREDEF_CALL, call_predefine_action, NULL,
659 ss_action_entry_add_internal(PREDEF_LOWMEM, lowmem_def_predefine_action,
661 ss_action_entry_add_internal(PREDEF_LOWBAT, lowbat_def_predefine_action,
663 ss_action_entry_add_internal(PREDEF_USBCON, usbcon_def_predefine_action,
665 ss_action_entry_add_internal(PREDEF_EARJACKCON,
666 earjackcon_def_predefine_action, NULL,
668 ss_action_entry_add_internal(PREDEF_POWEROFF,
669 poweroff_def_predefine_action, NULL, NULL);
670 ss_action_entry_add_internal(PREDEF_PWROFF_POPUP,
671 launching_predefine_action, NULL, NULL);
672 ss_action_entry_add_internal(PREDEF_REBOOT,
673 restart_def_predefine_action, NULL, NULL);
675 ss_action_entry_load_from_sodir();
677 /* check and set earjack init status */
678 earjackcon_def_predefine_action(0, NULL);