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 <utils/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
open_file_descriptors(const char * const paths[])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
initialize_fds(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
acquire_wake_lock(int lock,const char * id)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
release_wake_lock(const char * id)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