#include <fcntl.h>
|
#include <errno.h>
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <unistd.h>
|
#include <errno.h>
|
#include <string.h>
|
#include <pthread.h>
|
#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;
|
}
|