From 4ca66c4d62bd1867520ee42c7077503ac8582c10 Mon Sep 17 00:00:00 2001 From: Chao Chen Date: Wed, 17 Feb 2016 17:24:41 -0800 Subject: healthd: Separate power off alarm implementation into MSM specific HAL * Make the alarm implementation a separate HAL selected by BOARD_USES_QCOM_HARDWARE. REF: CYNGNOS-2073 Change-Id: I232c7999ebadff5c4e4e028c9cc2202441509fb7 --- healthd/Android.mk | 12 +- healthd/healthd_board_default.cpp | 2 - healthd/healthd_board_msm.cpp | 242 ++++++++++++++++++++++++++++++++++++++ healthd/healthd_msm.h | 20 ---- healthd/healthd_msm_alarm.cpp | 216 ---------------------------------- 5 files changed, 253 insertions(+), 239 deletions(-) create mode 100644 healthd/healthd_board_msm.cpp delete mode 100644 healthd/healthd_msm.h delete mode 100644 healthd/healthd_msm_alarm.cpp (limited to 'healthd') diff --git a/healthd/Android.mk b/healthd/Android.mk index 48d41f1..d1e005e 100644 --- a/healthd/Android.mk +++ b/healthd/Android.mk @@ -3,12 +3,18 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_SRC_FILES := healthd_board_default.cpp healthd_msm_alarm.cpp +LOCAL_SRC_FILES := healthd_board_default.cpp LOCAL_MODULE := libhealthd.default LOCAL_CFLAGS := -Werror include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) +LOCAL_SRC_FILES := healthd_board_msm.cpp +LOCAL_MODULE := libhealthd.msm +LOCAL_CFLAGS := -Werror +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) LOCAL_SRC_FILES := \ healthd.cpp \ @@ -55,6 +61,10 @@ endif LOCAL_HAL_STATIC_LIBRARIES := libhealthd +ifeq ($(BOARD_USES_QCOM_HARDWARE),true) +BOARD_HAL_STATIC_LIBRARIES ?= libhealthd.msm +endif + # Symlink /charger to /sbin/healthd LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT) \ && rm -f $(TARGET_ROOT_OUT)/charger && ln -sf /sbin/healthd $(TARGET_ROOT_OUT)/charger diff --git a/healthd/healthd_board_default.cpp b/healthd/healthd_board_default.cpp index cf5479a..c511c9c 100644 --- a/healthd/healthd_board_default.cpp +++ b/healthd/healthd_board_default.cpp @@ -15,12 +15,10 @@ */ #include -#include "healthd_msm.h" void healthd_board_init(struct healthd_config*) { // use defaults - power_off_alarm_init(); } diff --git a/healthd/healthd_board_msm.cpp b/healthd/healthd_board_msm.cpp new file mode 100644 index 0000000..1d62507 --- /dev/null +++ b/healthd/healthd_board_msm.cpp @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0) +#define LOGI(x...) do { KLOG_INFO("charger", x); } while (0) +#define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0) + +enum alarm_time_type { + ALARM_TIME, + 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) +{ + struct tm tm; + unsigned int cmd; + int rc, fd = -1; + + if (!secs) + return -1; + + fd = open("/dev/rtc0", O_RDWR); + if (fd < 0) { + LOGE("Can't open rtc devfs node\n"); + return -1; + } + + switch (time_type) { + case ALARM_TIME: + cmd = RTC_ALM_READ; + break; + case RTC_TIME: + cmd = RTC_RD_TIME; + break; + default: + LOGE("Invalid time type\n"); + goto err; + } + + rc = ioctl(fd, cmd, &tm); + if (rc < 0) { + LOGE("Unable to get time\n"); + goto err; + } + + *secs = mktime(&tm) + tm.tm_gmtoff; + if (*secs < 0) { + LOGE("Invalid seconds = %ld\n", *secs); + goto err; + } + + close(fd); + return 0; + +err: + close(fd); + return -1; +} + +#define ERR_SECS 2 +static int alarm_is_alm_expired() +{ + 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; +} + +static int alarm_set_reboot_time_and_wait(time_t secs) +{ + int rc, fd; + struct timespec ts; + + fd = open("/dev/alarm", O_RDWR); + if (fd < 0) { + LOGE("Can't open alarm devfs node\n"); + goto err; + } + + /* get the elapsed realtime from boot time to now */ + rc = ioctl(fd, ANDROID_ALARM_GET_TIME( + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP), &ts); + if (rc < 0) { + LOGE("Unable to get elapsed realtime\n"); + goto err; + } + + /* calculate the elapsed time from boot time to reboot time */ + ts.tv_sec += secs; + ts.tv_nsec = 0; + + rc = ioctl(fd, ANDROID_ALARM_SET( + ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP), &ts); + if (rc < 0) { + LOGE("Unable to set reboot time to %ld\n", secs); + goto err; + } + + do { + rc = ioctl(fd, ANDROID_ALARM_WAIT); + } while ((rc < 0 && errno == EINTR) || !alarm_is_alm_expired()); + + if (rc <= 0) { + LOGE("Unable to wait on alarm\n"); + goto err; + } + + close(fd); + return 0; + +err: + if (fd >= 0) + close(fd); + return -1; +} + +static void *alarm_thread(void *) +{ + time_t rtc_secs, rb_secs; + int rc; + + /* + * to support power off alarm, the time + * stored in alarm register at latest + * shutdown time should be some time + * earlier than the actual alarm time + * set by user + */ + rc = alarm_get_time(ALARM_TIME, &alm_secs); + if (rc < 0 || !alm_secs) + goto err; + + rc = alarm_get_time(RTC_TIME, &rtc_secs); + if (rc < 0) + goto err; + + /* + * calculate the reboot time after which + * the phone will reboot + */ + rb_secs = alm_secs - rtc_secs; + if (rb_secs <= 0) + goto err; + + rc = alarm_set_reboot_time_and_wait(rb_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; +} + +void healthd_board_init(struct healthd_config*) +{ + pthread_t tid; + int rc; + char value[PROP_VALUE_MAX]; + + property_get("ro.bootmode", value, ""); + if (!strcmp("charger", value)) { + rc = pthread_create(&tid, NULL, alarm_thread, NULL); + if (rc < 0) + LOGE("Create alarm thread failed\n"); + } +} + +int healthd_board_battery_update(struct android::BatteryProperties*) +{ + // return 0 to log periodic polled battery status to kernel log + return 1; +} + +void healthd_board_mode_charger_draw_battery(struct android::BatteryProperties*) +{ + +} + +void healthd_board_mode_charger_battery_update(struct android::BatteryProperties*) +{ + +} + +void healthd_board_mode_charger_set_backlight(bool) +{ + +} + +void healthd_board_mode_charger_init() +{ + +} diff --git a/healthd/healthd_msm.h b/healthd/healthd_msm.h deleted file mode 100644 index 6c46b20..0000000 --- a/healthd/healthd_msm.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _HEALTHD_MSM_H_ -#define _HEALTHD_MSM_H_ -void power_off_alarm_init(void); -#endif /* _HEALTHD_MSM_H_ */ diff --git a/healthd/healthd_msm_alarm.cpp b/healthd/healthd_msm_alarm.cpp deleted file mode 100644 index cbe809a..0000000 --- a/healthd/healthd_msm_alarm.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "healthd_msm.h" - -#define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0) -#define LOGI(x...) do { KLOG_INFO("charger", x); } while (0) -#define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0) - -enum alarm_time_type { - ALARM_TIME, - 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) -{ - struct tm tm; - unsigned int cmd; - int rc, fd = -1; - - if (!secs) - return -1; - - fd = open("/dev/rtc0", O_RDWR); - if (fd < 0) { - LOGE("Can't open rtc devfs node\n"); - return -1; - } - - switch (time_type) { - case ALARM_TIME: - cmd = RTC_ALM_READ; - break; - case RTC_TIME: - cmd = RTC_RD_TIME; - break; - default: - LOGE("Invalid time type\n"); - goto err; - } - - rc = ioctl(fd, cmd, &tm); - if (rc < 0) { - LOGE("Unable to get time\n"); - goto err; - } - - *secs = mktime(&tm) + tm.tm_gmtoff; - if (*secs < 0) { - LOGE("Invalid seconds = %ld\n", *secs); - goto err; - } - - close(fd); - return 0; - -err: - close(fd); - return -1; -} - -#define ERR_SECS 2 -static int alarm_is_alm_expired() -{ - 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; -} - -static int alarm_set_reboot_time_and_wait(time_t secs) -{ - int rc, fd; - struct timespec ts; - - fd = open("/dev/alarm", O_RDWR); - if (fd < 0) { - LOGE("Can't open alarm devfs node\n"); - goto err; - } - - /* get the elapsed realtime from boot time to now */ - rc = ioctl(fd, ANDROID_ALARM_GET_TIME( - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP), &ts); - if (rc < 0) { - LOGE("Unable to get elapsed realtime\n"); - goto err; - } - - /* calculate the elapsed time from boot time to reboot time */ - ts.tv_sec += secs; - ts.tv_nsec = 0; - - rc = ioctl(fd, ANDROID_ALARM_SET( - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP), &ts); - if (rc < 0) { - LOGE("Unable to set reboot time to %ld\n", secs); - goto err; - } - - do { - rc = ioctl(fd, ANDROID_ALARM_WAIT); - } while ((rc < 0 && errno == EINTR) || !alarm_is_alm_expired()); - - if (rc <= 0) { - LOGE("Unable to wait on alarm\n"); - goto err; - } - - close(fd); - return 0; - -err: - if (fd >= 0) - close(fd); - return -1; -} - -static void *alarm_thread(void *) -{ - time_t rtc_secs, rb_secs; - int rc; - - /* - * to support power off alarm, the time - * stored in alarm register at latest - * shutdown time should be some time - * earlier than the actual alarm time - * set by user - */ - rc = alarm_get_time(ALARM_TIME, &alm_secs); - if (rc < 0 || !alm_secs) - goto err; - - rc = alarm_get_time(RTC_TIME, &rtc_secs); - if (rc < 0) - goto err; - - /* - * calculate the reboot time after which - * the phone will reboot - */ - rb_secs = alm_secs - rtc_secs; - if (rb_secs <= 0) - goto err; - - rc = alarm_set_reboot_time_and_wait(rb_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; -} - -void power_off_alarm_init(void) -{ - pthread_t tid; - int rc; - char value[PROP_VALUE_MAX]; - - property_get("ro.bootmode", value, ""); - if (!strcmp("charger", value)) { - rc = pthread_create(&tid, NULL, alarm_thread, NULL); - if (rc < 0) - LOGE("Create alarm thread failed\n"); - } -} -- cgit v1.1