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
This commit is contained in:
parent
54529a8363
commit
7ec03e79f2
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/android_reboot.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <cutils/klog.h>
|
||||
#include <cutils/misc.h>
|
||||
#include <cutils/uevent.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <linux/android_alarm.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/time.h>
|
||||
#include <sys/epoll.h>
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue