#include #include #include #include #include #include #include #include #include "eq_log.h" #include "Rk_wake_lock.h" struct rk_wake_lock { char *id; }; #define TAG "WAKE_LOCK" #define debug(fmt, args...) \ eq_debug(TAG "[%s] " fmt "\n", __func__, ##args) enum { ACQUIRE_PARTIAL_WAKE_LOCK = 0, RELEASE_WAKE_LOCK, OUR_FD_COUNT }; const char * const WAKE_LOCK_PATHS[] = { "/sys/power/wake_lock", "/sys/power/wake_unlock", }; static int g_initialized = 0; static int g_fds[2]; static int g_error = -1; static int open_file_descriptors(const char * const paths[]) { for (int i = 0 ; i < 2; i++) { int fd = open(paths[i], O_RDWR | O_CLOEXEC); if (fd < 0) { g_error = -errno; debug("fatal error opening \"%s\": %s", paths[i], strerror(errno)); return -1; } g_fds[i] = fd; } g_error = 0; return 0; } static inline void initialize_fds(void) { if (g_initialized == 0) { open_file_descriptors(WAKE_LOCK_PATHS); g_initialized = 1; } } struct rk_wake_lock* RK_wake_lock_new(const char *id) { struct rk_wake_lock* lock; if (!id) return NULL; initialize_fds(); lock = (struct rk_wake_lock*)malloc(sizeof(struct rk_wake_lock)); lock->id = strdup(id); return lock; } void RK_wake_lock_delete(struct rk_wake_lock* lock) { if (lock && lock->id) free(lock->id); if (lock) free(lock); } int RK_acquire_wake_lock(struct rk_wake_lock *wake_lock) { char *id = wake_lock->id; debug("id=%s", id); if (g_error) return g_error; int fd; size_t len; ssize_t ret; fd = g_fds[0]; ret = write(fd, id, strlen(id)); if (ret < 0) { return -errno; } return ret; } int RK_release_wake_lock(struct rk_wake_lock *wake_lock) { char *id = wake_lock->id; int fd; debug("id=%s", id); if (g_error) return g_error; fd = g_fds[1]; ssize_t len = write(fd, id, strlen(id)); if (len < 0) { return -errno; } return len; } static int exec(const char *cmd, char *buf, const size_t size) { FILE *stream = NULL; char tmp[1024]; if ((stream = popen(cmd,"r")) == NULL) { return -1; } if (buf == NULL) { pclose(stream); return -2; } buf[0] = '\0'; while (fgets(tmp, sizeof(tmp) -1, stream)) { if (strlen(buf) + strlen(tmp) >= size) { pclose(stream); return -3; } strcat(buf, tmp); } pclose(stream); return 0; } int RK_wait_all_wake_lock_release(int timeout_ms) { int cnt = timeout_ms / 10; char result[1024]; while(cnt--) { memset(result, 0, 1024); exec("cat /sys/power/wake_lock", result, 1024); if (strlen(result) <= 1) //换行符 break; usleep(10*1000); debug("## suspend waiting wake_lock: %s", result); } if (cnt == 0) { debug("wait suspend timeout, abort suspend"); debug("unreleased wake_lock: %s", result); return -1; } return 0; }