OSDN Git Service

9250d08d0c86a79e3f83fad97f45bc7f737f23b5
[android-x86/hardware-libhardware_legacy.git] / power / power.c
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 }