From 7ec03e79f2499f502eebcd403f18e5b656c6d251 Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Mon, 12 Jun 2017 16:09:07 +0800 Subject: [PATCH] healthd : Changes of power off charging alarm 1. Start alarm thread when device enters power off charging mode. Reboot the device when alarm time is up during power off charging. 2. Add reboot function to event data.If the alarm event happens, call reboot function immediately to ensure that device won't go to suspend during calling reboot function. 3. Add alarm seconds check in case of that power off alarm time is up when start alarm thread. If the final alarm time is less than the estimated time of next boot completed to fire, that means it is not able to fire the last power off alarm at the right time, so just miss it. CRs-Fixed: 2054302 Change-Id: I40bd9c35a9e42aeabb742603e161c2049cd0b5f5 --- healthd/Android.mk | 8 ++-- healthd/healthd_board_msm.cpp | 2 - healthd/healthd_msm_alarm.cpp | 79 ++++++++++++++++++++++------------- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/healthd/Android.mk b/healthd/Android.mk index 206309d4..776680b9 100644 --- a/healthd/Android.mk +++ b/healthd/Android.mk @@ -1,16 +1,14 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES := healthd_board_msm.cpp +LOCAL_SRC_FILES := healthd_board_msm.cpp healthd_msm_alarm.cpp LOCAL_MODULE := libhealthd.msm + LOCAL_CFLAGS := -Werror LOCAL_C_INCLUDES := \ system/core/healthd/include/healthd/ \ system/core/base/include \ bootable/recovery \ bootable/recovery/minui/include -ifneq ($(TARGET_USES_AOSP),true) -LOCAL_SRC_FILES += healthd_msm_alarm.cpp -LOCAL_CFLAGS += -DQTI_BSP=1 -endif + include $(BUILD_STATIC_LIBRARY) diff --git a/healthd/healthd_board_msm.cpp b/healthd/healthd_board_msm.cpp index c045ffce..daa564f9 100644 --- a/healthd/healthd_board_msm.cpp +++ b/healthd/healthd_board_msm.cpp @@ -450,9 +450,7 @@ out: void healthd_board_init(struct healthd_config*) { // use defaults -#if QTI_BSP power_off_alarm_init(); -#endif healthd_batt_info_notify(); } diff --git a/healthd/healthd_msm_alarm.cpp b/healthd/healthd_msm_alarm.cpp index 5afd3cce..f7e6f0fe 100644 --- a/healthd/healthd_msm_alarm.cpp +++ b/healthd/healthd_msm_alarm.cpp @@ -24,14 +24,14 @@ #include #include -#include +#include +#include +#include #include #include #include #include - #include -#include #include #include #include @@ -47,12 +47,6 @@ enum alarm_time_type { RTC_TIME, }; -/* - * shouldn't be changed after - * reading from alarm register - */ -static time_t alm_secs; - static int alarm_get_time(enum alarm_time_type time_type, time_t *secs) { @@ -101,18 +95,11 @@ err: return -1; } -#define ERR_SECS 2 -static int alarm_is_alm_expired() +static void alarm_reboot(void) { - int rc; - time_t rtc_secs; - - rc = alarm_get_time(RTC_TIME, &rtc_secs); - if (rc < 0) - return 0; - - return (alm_secs >= rtc_secs - ERR_SECS && - alm_secs <= rtc_secs + ERR_SECS) ? 1 : 0; + LOGI("alarm time is up, reboot the phone!\n"); + syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, + LINUX_REBOOT_CMD_RESTART2, "rtc"); } static int alarm_set_reboot_time_and_wait(time_t secs) @@ -136,6 +123,7 @@ static int alarm_set_reboot_time_and_wait(time_t secs) } event.events = EPOLLIN | EPOLLWAKEUP; + event.data.ptr = (void *)alarm_reboot; rc = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event); if (rc < 0) { LOGE("epoll_ctl(EPOLL_CTL_ADD) failed \n"); @@ -154,13 +142,13 @@ static int alarm_set_reboot_time_and_wait(time_t secs) goto err; } - do { - nevents = epoll_wait(epollfd, events, 1, -1); - } while ((nevents < 0) || !alarm_is_alm_expired()); + nevents = epoll_wait(epollfd, events, 1, -1); if (nevents <= 0) { LOGE("Unable to wait on alarm\n"); goto err; + } else { + (*(void (*)())events[0].data.ptr)(); } close(epollfd); @@ -176,10 +164,19 @@ err: return -1; } +/* + * 10s the estimated time from timestamp of alarm thread start + * to timestamp of android boot completed. + */ +#define TIME_DELTA 10 + +/* seconds of 1 minute*/ +#define ONE_MINUTE 60 static void *alarm_thread(void *) { - time_t rtc_secs, rb_secs; + time_t rtc_secs, alarm_secs; int rc; + timespec ts; /* * to support power off alarm, the time @@ -188,17 +185,39 @@ static void *alarm_thread(void *) * earlier than the actual alarm time * set by user */ - rc = alarm_get_time(ALARM_TIME, &alm_secs); - if (rc < 0 || !alm_secs) + rc = alarm_get_time(ALARM_TIME, &alarm_secs); + if (rc < 0 || !alarm_secs) goto err; - rc = alarm_set_reboot_time_and_wait(alm_secs); + rc = alarm_get_time(RTC_TIME, &rtc_secs); + if (rc < 0 || !rtc_secs) + goto err; + LOGI("alarm time in rtc is %ld, rtc time is %ld\n", alarm_secs, rtc_secs); + + if (alarm_secs <= rtc_secs) { + clock_gettime(CLOCK_BOOTTIME, &ts); + + /* + * It is possible that last power off alarm time is up at this point. + * (alarm_secs + ONE_MINUTE) is the final alarm time to fire. + * (rtc_secs + ts.tv_sec + TIME_DELTA) is the estimated time of next + * boot completed to fire alarm. + * If the final alarm time is less than the estimated time of next boot + * completed to fire, that means it is not able to fire the last power + * off alarm at the right time, so just miss it. + */ + if (alarm_secs + ONE_MINUTE < rtc_secs + ts.tv_sec + TIME_DELTA) { + LOGE("alarm is missed\n"); + goto err; + } + + alarm_reboot(); + } + + rc = alarm_set_reboot_time_and_wait(alarm_secs); if (rc < 0) goto err; - LOGI("Exit from power off charging, reboot the phone!\n"); - android_reboot(ANDROID_RB_RESTART2, 0, (char *)"rtc"); - err: LOGE("Exit from alarm thread\n"); return NULL;