Home | History | Annotate | Download | only in libhardware_legacy
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #include <hardware_legacy/power.h>
     17 #include <fcntl.h>
     18 #include <errno.h>
     19 #include <stdlib.h>
     20 #include <stdio.h>
     21 #include <unistd.h>
     22 #include <errno.h>
     23 #include <string.h>
     24 #include <sys/stat.h>
     25 #include <sys/types.h>
     26 #include <pthread.h>
     27 
     28 #define LOG_TAG "power"
     29 #include <log/log.h>
     30 
     31 enum {
     32     ACQUIRE_PARTIAL_WAKE_LOCK = 0,
     33     RELEASE_WAKE_LOCK,
     34     OUR_FD_COUNT
     35 };
     36 
     37 const char * const OLD_PATHS[] = {
     38     "/sys/android_power/acquire_partial_wake_lock",
     39     "/sys/android_power/release_wake_lock",
     40 };
     41 
     42 const char * const NEW_PATHS[] = {
     43     "/sys/power/wake_lock",
     44     "/sys/power/wake_unlock",
     45 };
     46 
     47 //XXX static pthread_once_t g_initialized = THREAD_ONCE_INIT;
     48 static int g_initialized = 0;
     49 static int g_fds[OUR_FD_COUNT];
     50 static int g_error = -1;
     51 
     52 static int
     53 open_file_descriptors(const char * const paths[])
     54 {
     55     int i;
     56     for (i=0; i<OUR_FD_COUNT; i++) {
     57         int fd = open(paths[i], O_RDWR | O_CLOEXEC);
     58         if (fd < 0) {
     59             g_error = -errno;
     60             fprintf(stderr, "fatal error opening \"%s\": %s\n", paths[i],
     61                 strerror(errno));
     62             return -1;
     63         }
     64         g_fds[i] = fd;
     65     }
     66 
     67     g_error = 0;
     68     return 0;
     69 }
     70 
     71 static inline void
     72 initialize_fds(void)
     73 {
     74     // XXX: should be this:
     75     //pthread_once(&g_initialized, open_file_descriptors);
     76     // XXX: not this:
     77     if (g_initialized == 0) {
     78         if(open_file_descriptors(NEW_PATHS) < 0)
     79             open_file_descriptors(OLD_PATHS);
     80         g_initialized = 1;
     81     }
     82 }
     83 
     84 int
     85 acquire_wake_lock(int lock, const char* id)
     86 {
     87     initialize_fds();
     88 
     89 //    ALOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id);
     90 
     91     if (g_error) return g_error;
     92 
     93     int fd;
     94     size_t len;
     95     ssize_t ret;
     96 
     97     if (lock != PARTIAL_WAKE_LOCK) {
     98         return -EINVAL;
     99     }
    100 
    101     fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
    102 
    103     ret = write(fd, id, strlen(id));
    104     if (ret < 0) {
    105         return -errno;
    106     }
    107 
    108     return ret;
    109 }
    110 
    111 int
    112 release_wake_lock(const char* id)
    113 {
    114     initialize_fds();
    115 
    116 //    ALOGI("release_wake_lock id='%s'\n", id);
    117 
    118     if (g_error) return g_error;
    119 
    120     ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id));
    121     if (len < 0) {
    122         return -errno;
    123     }
    124     return len;
    125 }
    126