• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <sys/time.h>
23 #include <time.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <pthread.h>
29 
30 #define LOG_TAG "power"
31 #include <utils/Log.h>
32 
33 enum {
34     ACQUIRE_PARTIAL_WAKE_LOCK = 0,
35     RELEASE_WAKE_LOCK,
36     OUR_FD_COUNT
37 };
38 
39 const char * const OLD_PATHS[] = {
40     "/sys/android_power/acquire_partial_wake_lock",
41     "/sys/android_power/release_wake_lock",
42 };
43 
44 const char * const NEW_PATHS[] = {
45     "/sys/power/wake_lock",
46     "/sys/power/wake_unlock",
47 };
48 
49 //XXX static pthread_once_t g_initialized = THREAD_ONCE_INIT;
50 static int g_initialized = 0;
51 static int g_fds[OUR_FD_COUNT];
52 static int g_error = 1;
53 
systemTime()54 static int64_t systemTime()
55 {
56     struct timespec t;
57     t.tv_sec = t.tv_nsec = 0;
58     clock_gettime(CLOCK_MONOTONIC, &t);
59     return t.tv_sec*1000000000LL + t.tv_nsec;
60 }
61 
62 static int
open_file_descriptors(const char * const paths[])63 open_file_descriptors(const char * const paths[])
64 {
65     int i;
66     for (i=0; i<OUR_FD_COUNT; i++) {
67         int fd = open(paths[i], O_RDWR | O_CLOEXEC);
68         if (fd < 0) {
69             fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);
70             g_error = errno;
71             return -1;
72         }
73         g_fds[i] = fd;
74     }
75 
76     g_error = 0;
77     return 0;
78 }
79 
80 static inline void
initialize_fds(void)81 initialize_fds(void)
82 {
83     // XXX: should be this:
84     //pthread_once(&g_initialized, open_file_descriptors);
85     // XXX: not this:
86     if (g_initialized == 0) {
87         if(open_file_descriptors(NEW_PATHS) < 0)
88             open_file_descriptors(OLD_PATHS);
89         g_initialized = 1;
90     }
91 }
92 
93 int
acquire_wake_lock(int lock,const char * id)94 acquire_wake_lock(int lock, const char* id)
95 {
96     initialize_fds();
97 
98 //    ALOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id);
99 
100     if (g_error) return g_error;
101 
102     int fd;
103 
104     if (lock == PARTIAL_WAKE_LOCK) {
105         fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
106     }
107     else {
108         return EINVAL;
109     }
110 
111     return write(fd, id, strlen(id));
112 }
113 
114 int
release_wake_lock(const char * id)115 release_wake_lock(const char* id)
116 {
117     initialize_fds();
118 
119 //    ALOGI("release_wake_lock id='%s'\n", id);
120 
121     if (g_error) return g_error;
122 
123     ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id));
124     return len >= 0;
125 }
126