2 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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;
98 if (localtime_r(&now, &cur_tm) == NULL) {
99 PRT_TRACE_ERR("Fail to get localtime");
103 PRT_TRACE("%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
104 pid, (1900 + cur_tm.tm_year), 1 + cur_tm.tm_mon,
105 cur_tm.tm_mday, cur_tm.tm_hour, cur_tm.tm_min,
107 snprintf(new_log, sizeof(new_log),
108 "%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,
113 snprintf(params, sizeof(params), "-f %s", new_log);
114 ret = ss_launch_evenif_exist(MEMPS_EXEC_PATH, params);
119 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", ret);
120 fp = fopen(buf, "w");
122 fprintf(fp, "%d", (-17));
128 static int lowmem_get_victim_pid()
133 if (0 > plugin_intf->OEM_sys_get_memnotify_victim_task(&pid)) {
134 PRT_TRACE_ERR("Get victim task failed");
141 int lowmem_def_predefine_action(int argc, char **argv)
143 int pid, ret, oom_adj;
144 char appname[PATH_MAX];
149 if (!strcmp(argv[0], OOM_MEM_ACT)) {
150 pid = lowmem_get_victim_pid();
151 if (pid > 0 && pid != sysman_get_pid(LOWMEM_EXEC_PATH) && pid != sysman_get_pid(MEMPS_EXEC_PATH)) {
152 if ((sysman_get_cmdline_name(pid, appname, PATH_MAX)) ==
155 ("we will kill, lowmem lv2 = %d (%s)\n",
158 make_memps_log(MEMPS_LOG_FILE, pid, appname);
160 if(get_app_oomadj(pid, &oom_adj) < 0) {
161 PRT_TRACE_ERR("Failed to get oom_adj");
163 PRT_TRACE("%d will be killed with %d oom_adj value", pid, oom_adj);
167 if (oom_adj != OOMADJ_FOREGRD_LOCKED && oom_adj != OOMADJ_FOREGRD_UNLOCKED) {
174 bundle_add(b, "_APP_NAME_", appname);
175 ret = syspopup_launch("lowmem-syspopup", b);
178 PRT_TRACE_EM("popup lauch failed\n");
182 if (set_app_oomadj(ret, OOMADJ_SU) < 0) {
183 PRT_TRACE_ERR("Failed to set oom_adj");
191 int usbcon_def_predefine_action(int argc, char **argv)
196 int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
198 if (plugin_intf->OEM_sys_get_jack_usb_online(&val) == 0) {
200 vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
201 VCONFKEY_SYSMAN_USB_DISCONNECTED);
202 pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
206 vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
207 VCONFKEY_SYSMAN_USB_AVAILABLE);
208 pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
209 pid = ss_launch_if_noexist(USBCON_EXEC_PATH, NULL);
211 PRT_TRACE_ERR("usb predefine action failed\n");
216 PRT_TRACE_ERR("failed to get usb status\n");
220 int earjackcon_def_predefine_action(int argc, char **argv)
224 PRT_TRACE_EM("earjack_normal predefine action\n");
225 if (plugin_intf->OEM_sys_get_jack_earjack_online(&val) == 0) {
226 return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
232 int lowbat_popup(void *data)
234 int ret = -1, state = 0;
235 ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
236 if (state == 1 || ret != 0) {
239 if(lowbat_popup_option == LOWBAT_OPT_WARNING) {
240 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
241 } else if(lowbat_popup_option == LOWBAT_OPT_POWEROFF) {
242 bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
243 } else if(lowbat_popup_option == LOWBAT_OPT_CHARGEERR) {
244 bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
246 bundle_add(b, "_SYSPOPUP_CONTENT_", "check");
249 ret = syspopup_launch("lowbat-syspopup", b);
251 PRT_TRACE_EM("popup lauch failed\n");
255 lowbat_popup_id = NULL;
256 lowbat_popup_option = 0;
259 PRT_TRACE_EM("boot-animation running yet");
266 int lowbat_def_predefine_action(int argc, char **argv)
275 if(lowbat_popup_id != NULL) {
276 ecore_timer_del(lowbat_popup_id);
277 lowbat_popup_id = NULL;
282 if(!strcmp(argv[0],WARNING_LOW_BAT_ACT) || !strcmp(argv[0],CRITICAL_LOW_BAT_ACT)) {
283 bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
284 lowbat_popup_option = LOWBAT_OPT_WARNING;
285 } else if(!strcmp(argv[0],POWER_OFF_BAT_ACT)) {
286 bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
287 lowbat_popup_option = LOWBAT_OPT_POWEROFF;
288 } else if(!strcmp(argv[0],CHARGE_ERROR_ACT)) {
289 bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
290 lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
292 bundle_add(b, "_SYSPOPUP_CONTENT_", "check");
293 lowbat_popup_option = LOWBAT_OPT_CHECK;
296 ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
297 if (state == 1 || ret != 0) {
298 ret = syspopup_launch("lowbat-syspopup", b);
300 PRT_TRACE_EM("popup lauch failed\n");
302 lowbat_popup_option = 0;
306 PRT_TRACE_EM("boot-animation running yet");
307 lowbat_popup_id = ecore_timer_add(1, lowbat_popup, NULL);
313 Eina_Bool powerdown_ap_by_force(void *data)
316 int poweroff_duration = POWEROFF_DURATION;
319 if(tapi_handle != NULL)
321 tel_deinit(tapi_handle);
324 /* Getting poweroff duration */
325 buf = getenv("PWROFF_DUR");
326 if (buf != NULL && strlen(buf) < 1024)
327 poweroff_duration = atoi(buf);
328 if (poweroff_duration < 0 || poweroff_duration > 60)
329 poweroff_duration = POWEROFF_DURATION;
331 gettimeofday(&now, NULL);
332 /* Waiting until power off duration and displaying animation */
333 while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
335 gettimeofday(&now, NULL);
338 PRT_TRACE("Power off by force\n");
340 /* give a chance to be terminated for each process */
343 reboot(RB_POWER_OFF);
347 static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
350 int poweroff_duration = POWEROFF_DURATION;
353 if (poweroff_timer_id) {
354 ecore_timer_del(poweroff_timer_id);
355 poweroff_timer_id = NULL;
358 tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
359 tel_deinit(tapi_handle);
362 PRT_TRACE("Power off \n");
364 /* Getting poweroff duration */
365 buf = getenv("PWROFF_DUR");
366 if (buf != NULL && strlen(buf) < 1024)
367 poweroff_duration = atoi(buf);
368 if (poweroff_duration < 0 || poweroff_duration > 60)
369 poweroff_duration = POWEROFF_DURATION;
371 gettimeofday(&now, NULL);
372 /* Waiting until power off duration and displaying animation */
373 while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
375 gettimeofday(&now, NULL);
379 /* give a chance to be terminated for each process */
382 reboot(RB_POWER_OFF);
384 static void powerdown_res_cb(TapiHandle *handle, int result, void *data, void *user_data)
386 PRT_TRACE("poweroff command request : %d",result);
388 int poweroff_def_predefine_action(int argc, char **argv)
392 heynoti_publish(POWEROFF_NOTI_NAME);
394 pm_change_state(LCD_NORMAL);
395 system("/etc/rc.d/rc.shutdown &");
398 gettimeofday(&tv_start_poweroff, NULL);
400 ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, powerdown_ap, NULL);
402 if (ret != TAPI_API_SUCCESS) {
404 ("tel_register_event is not subscribed. error %d\n", ret);
405 powerdown_ap_by_force(NULL);
409 ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
410 if (ret != TAPI_API_SUCCESS) {
411 PRT_TRACE_ERR("tel_process_power_command() error %d\n", ret);
412 powerdown_ap_by_force(NULL);
415 poweroff_timer_id = ecore_timer_add(15, powerdown_ap_by_force, NULL);
417 powerdown_ap_by_force(NULL);
422 static void enter_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
424 int bCurFlightMode = 0;
425 if (result != TAPI_POWER_FLIGHT_MODE_ENTER) {
426 PRT_TRACE_ERR("flight mode enter failed %d",result);
428 PRT_TRACE("enter flight mode result : %d",result);
429 if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,&bCurFlightMode) == 0) {
430 PRT_TRACE("Flight Mode is %d", bCurFlightMode);
432 PRT_TRACE_ERR("failed to get vconf key");
437 static void leave_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
439 int bCurFlightMode = 0;
440 if (result != TAPI_POWER_FLIGHT_MODE_LEAVE) {
441 PRT_TRACE_ERR("flight mode leave failed %d",result);
443 PRT_TRACE("leave flight mode result : %d",result);
444 if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,&bCurFlightMode) == 0) {
445 PRT_TRACE("Flight Mode is %d", bCurFlightMode);
447 PRT_TRACE_ERR("failed to get vconf key");
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 int flight_mode_def_predefine_action(int argc, char **argv)
610 int err = TAPI_API_SUCCESS;
611 if (argc != 1 || argv[0] == NULL) {
612 PRT_TRACE_ERR("FlightMode Set predefine action failed");
615 bCurFlightMode = atoi(argv[0]);
616 if (bCurFlightMode == 1) {
617 err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE, leave_flight_mode_cb, NULL);
618 } else if (bCurFlightMode == 0) {
619 err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER, enter_flight_mode_cb, NULL);
621 if (err != TAPI_API_SUCCESS)
622 PRT_TRACE_ERR("FlightMode tel api action failed %d",err);
626 static void ss_action_entry_load_from_sodir()
629 struct dirent *dentry;
634 dp = opendir(PREDEFINE_SO_DIR);
636 ERR("fail open %s", PREDEFINE_SO_DIR);
640 msg = malloc(sizeof(struct sysnoti));
642 ERR("Malloc failed");
649 while ((dentry = readdir(dp)) != NULL) {
650 if ((ext = strstr(dentry->d_name, ".so")) == NULL)
653 snprintf(tmp, sizeof(tmp), "%s/%s", PREDEFINE_SO_DIR,
657 msg->type = &(dentry->d_name[3]);
658 ss_action_entry_add(msg);
664 static void __tel_init_cb(keynode_t *key_nodes,void *data)
667 bTelReady = vconf_keynode_get_bool(key_nodes);
668 if (bTelReady == 1) {
669 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, (void*)__tel_init_cb);
670 tapi_handle = tel_init(NULL);
671 if (tapi_handle == NULL) {
672 PRT_TRACE_ERR("tapi init error");
675 PRT_TRACE_ERR("tapi is not ready yet");
678 void ss_predefine_internal_init(void)
681 /* telephony initialize */
684 if (vconf_get_bool(VCONFKEY_TELEPHONY_READY,&bTelReady) == 0) {
685 if (bTelReady == 1) {
686 tapi_handle = tel_init(NULL);
687 if (tapi_handle == NULL) {
688 PRT_TRACE_ERR("tapi init error");
691 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY, (void *)__tel_init_cb, NULL);
694 PRT_TRACE_ERR("failed to get tapi vconf key");
697 ss_action_entry_add_internal(PREDEF_CALL, call_predefine_action, NULL,
700 ss_action_entry_add_internal(PREDEF_LOWMEM, lowmem_def_predefine_action,
702 ss_action_entry_add_internal(PREDEF_LOWBAT, lowbat_def_predefine_action,
704 ss_action_entry_add_internal(PREDEF_USBCON, usbcon_def_predefine_action,
706 ss_action_entry_add_internal(PREDEF_EARJACKCON,
707 earjackcon_def_predefine_action, NULL,
709 ss_action_entry_add_internal(PREDEF_POWEROFF,
710 poweroff_def_predefine_action, NULL, NULL);
711 ss_action_entry_add_internal(PREDEF_PWROFF_POPUP,
712 launching_predefine_action, NULL, NULL);
713 ss_action_entry_add_internal(PREDEF_REBOOT,
714 restart_def_predefine_action, NULL, NULL);
716 ss_action_entry_add_internal(PREDEF_FLIGHT_MODE,
717 flight_mode_def_predefine_action, NULL, NULL);
718 ss_action_entry_load_from_sodir();
720 /* check and set earjack init status */
721 earjackcon_def_predefine_action(0, NULL);