blob: ab25410b177a0b9ea9b1209c32a0e3118ffe87c8 [file] [log] [blame]
liuyang34770f82024-11-14 17:26:24 +08001#include <pthread.h>
2#include <sys/epoll.h>
3#include <sys/timerfd.h>
4
5
6
r.xiao27072552024-10-24 01:02:48 -07007#include "mbtk_sleep.h"
8#include "mbtk_log.h"
b.liu9e8584b2024-11-06 19:21:28 +08009#include "mbtk_utils.h"
r.xiao27072552024-10-24 01:02:48 -070010
b.liuacb8b4a2024-11-19 15:50:11 +080011static bool autosleep_enable = FALSE;
12
r.xiao72f92372024-10-28 04:00:43 -070013static mbtk_lock_name_s mbtk_lock_name[LOCK_MAX_SIZE]={0};
r.xiao27072552024-10-24 01:02:48 -070014
b.liuacb8b4a2024-11-19 15:50:11 +080015#define EPOLL_SIZE_HINT 128
liuyang83375062024-11-22 17:49:49 +080016int g_mEpollFd = -1;
b.liu670a7892024-11-21 18:38:54 +080017mbtk_sleep_callback_func g_sleep_timer_cb;
liuyang34770f82024-11-14 17:26:24 +080018int g_sleep_timer_fd = 0;
liuyang83375062024-11-22 17:49:49 +080019pthread_t g_timer_thread_id;
20
21
liuyang34770f82024-11-14 17:26:24 +080022
r.xiao27072552024-10-24 01:02:48 -070023
24int mbtk_autosuspend_enable(char enable)
25{
26 if((enable == 1) || enable == '1')
27 {
28 if(!access("/sys/power/autosleep", W_OK))
29 {
b.liu9e8584b2024-11-06 19:21:28 +080030 mbtk_system("echo mem > /sys/power/autosleep");
r.xiao27072552024-10-24 01:02:48 -070031 autosleep_enable = TRUE;
32 return 0;
33 }
34 else
35 {
36 LOGE("/sys/power/autosleep can not write.");
37 return -1;
38 }
39 }
40 else if((enable == 0) || enable == '0')
41 {
42 if(!access("/sys/power/autosleep", W_OK))
43 {
b.liu9e8584b2024-11-06 19:21:28 +080044 mbtk_system("echo off > /sys/power/autosleep");
r.xiao27072552024-10-24 01:02:48 -070045 autosleep_enable = FALSE;
46 return 0;
47 }
48 else
49 {
50 LOGE("/sys/power/autosleep can not write.");
51 return -1;
52 }
53 }
54 else
55 {
56 LOGE("qser_autosuspend_enablecan enable err.");
57 return -1;
58 }
59
60 return 0;
61}
62
63int mbtk_wakelock_create(const char* name , size_t len)
64{
65 int len_t;
66
67 len_t = strlen(name);
68
69 if((name != NULL) && (len < 33) && (len_t < 33))
70 {
71 int i;
72 for(i=1 ;i<LOCK_MAX_SIZE;i++)
73 {
74 if(strcmp(mbtk_lock_name[i].name, name) == 0)
75 {
76 LOGE("Repeated names.");
77 return -1;
78 }
79 }
80
81 for(i=1 ;i<LOCK_MAX_SIZE;i++)
82 {
83 if(mbtk_lock_name[i].fd == 0)
84 break;
85 }
b.liu9e8584b2024-11-06 19:21:28 +080086
r.xiao27072552024-10-24 01:02:48 -070087 if (i >= LOCK_MAX_SIZE)
88 {
89 LOGE("Fd is full.");
90 return -1;
91 }
92
93 memcpy(mbtk_lock_name[i].name, name, strlen(name)+1);
94 mbtk_lock_name[i].fd = i;
95 return mbtk_lock_name[i].fd -1;//Starting from scratch
96 }
97 else
98 return -1;
99
100 return -1;
101}
102
103int mbtk_wakelock_lock(int fd)
104{
105 int i;
106 for(i=1;i<LOCK_MAX_SIZE;i++)
107 {
108 if(mbtk_lock_name[i].fd -1 == fd)
109 break;
110 }
111 if(i == LOCK_MAX_SIZE)
112 {
113 LOGE("LOCK_MAX_SIZE is full\n");
114 return -1;
115 }
116
117 if(!access("/sys/power/wake_lock", W_OK))
118 {
119 char cmd[128]={0};
120 sprintf(cmd, "echo %s > /sys/power/wake_lock", mbtk_lock_name[i].name);
b.liu9e8584b2024-11-06 19:21:28 +0800121 mbtk_system(cmd);
r.xiao27072552024-10-24 01:02:48 -0700122 return 0;
123 }
124 else
125 {
126 LOGE("/sys/power/wake_lock can not write.");
127 return -1;
128 }
129
130 return 0;
131}
132
133int mbtk_wakelock_unlock(int fd)
134{
135 int i;
136 for(i=1;i<LOCK_MAX_SIZE;i++)
137 {
138 if(mbtk_lock_name[i].fd -1 == fd)
139 break;
140 }
141 if(i == LOCK_MAX_SIZE)
142 {
143 LOGE("LOCK_MAX_SIZE is full\n");
144 return -1;
145 }
146
147 if(!access("/sys/power/wake_unlock", W_OK))
148 {
149 char cmd[128]={0};
150 sprintf(cmd, "echo %s > /sys/power/wake_unlock", mbtk_lock_name[i].name);
b.liu9e8584b2024-11-06 19:21:28 +0800151 mbtk_system(cmd);
r.xiao27072552024-10-24 01:02:48 -0700152 return 0;
153 }
154 else
155 {
156 LOGE("/sys/power/wake_unlock can not write.");
157 return -1;
158 }
159
160 return 0;
161}
162
163int mbtk_wakelock_destroy(int fd)
164{
165 int i;
166 for(i=1;i<LOCK_MAX_SIZE;i++)
167 {
168 if(mbtk_lock_name[i].fd -1 == fd)
169 break;
170 }
171
172 if(i == LOCK_MAX_SIZE)
173 {
174 LOGE("LOCK_MAX_SIZE is full\n");
175 return -1;
176 }
177 else
178 {
179 mbtk_lock_name[i].fd = 0;
180 memset(mbtk_lock_name[i].name, 0, 64);
181 return 0;
182 }
183
184 return 0;
185}
186
liuyang34770f82024-11-14 17:26:24 +0800187static void* suspend_timer_thread_run(void* arg)
188{
189 struct epoll_event eventItems[EPOLL_SIZE_HINT];
liuyang83375062024-11-22 17:49:49 +0800190 int eventCount = epoll_wait(g_mEpollFd, eventItems, EPOLL_SIZE_HINT, -1);
b.liuacb8b4a2024-11-19 15:50:11 +0800191
liuyang34770f82024-11-14 17:26:24 +0800192 int timerFd = -1;
193 int eventIndex = 0;
194 uint64_t readCounter;
b.liuacb8b4a2024-11-19 15:50:11 +0800195
liuyang34770f82024-11-14 17:26:24 +0800196 if (eventCount < 0) {
197 LOGE("Poll failed with an unexpected error: %s\n", strerror(errno));
198 return (void*)-1;
199 }
b.liuacb8b4a2024-11-19 15:50:11 +0800200
liuyang83375062024-11-22 17:49:49 +0800201 for (; eventIndex < eventCount; ++eventIndex)
202 {
liuyang34770f82024-11-14 17:26:24 +0800203 timerFd = eventItems[eventIndex].data.fd;
b.liuacb8b4a2024-11-19 15:50:11 +0800204
liuyang34770f82024-11-14 17:26:24 +0800205 int retRead = read(timerFd, &readCounter, sizeof(uint64_t));
liuyang83375062024-11-22 17:49:49 +0800206
207
208 if (retRead < 0)
209 {
liuyang34770f82024-11-14 17:26:24 +0800210 LOGE("read %d failed...\n", timerFd);
liuyang34770f82024-11-14 17:26:24 +0800211 continue;
liuyang83375062024-11-22 17:49:49 +0800212 }
213 else
214 {
liuyang34770f82024-11-14 17:26:24 +0800215 g_sleep_timer_cb(NULL, 0);
216 mbtk_autosuspend_enable(0);
217 g_sleep_timer_fd = 0;
liuyang83375062024-11-22 17:49:49 +0800218 LOGI("suspend_timer_success, retRead:%d\n", retRead);
liuyang34770f82024-11-14 17:26:24 +0800219 }
liuyang83375062024-11-22 17:49:49 +0800220
liuyang34770f82024-11-14 17:26:24 +0800221 }
b.liuacb8b4a2024-11-19 15:50:11 +0800222
liuyang34770f82024-11-14 17:26:24 +0800223 return 0;
224}
225
226
227
228static int suspend_timer_timer_init(void)
229{
230 pthread_attr_t thread_attr;
liuyang34770f82024-11-14 17:26:24 +0800231 pthread_attr_init(&thread_attr);
232 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
233 {
234 LOGE("[suspend] pthread_attr_setdetachstate() fail.");
235 return -1;
236 }
237
liuyang83375062024-11-22 17:49:49 +0800238 if(pthread_create(&g_timer_thread_id, &thread_attr, suspend_timer_thread_run, NULL))
liuyang34770f82024-11-14 17:26:24 +0800239 {
240 LOGE("[suspend] pthread_create() fail.");
241 return -1;
242 }
243
244 pthread_attr_destroy(&thread_attr);
245 return 0;
246}
247
248
liuyang83375062024-11-22 17:49:49 +0800249
250
b.liu670a7892024-11-21 18:38:54 +0800251int mbtk_suspend_timer_set(int time, mbtk_sleep_callback_func cb)
liuyang34770f82024-11-14 17:26:24 +0800252{
liuyang83375062024-11-22 17:49:49 +0800253 struct itimerspec timerSet;
254 struct epoll_event eventItem;
255 int result = 0;
256
liuyang34770f82024-11-14 17:26:24 +0800257 if(0 < g_sleep_timer_fd)
258 {
liuyang83375062024-11-22 17:49:49 +0800259 LOGE("suspend timer has been init, restart");
260 if(timerfd_settime(g_sleep_timer_fd, TFD_TIMER_CANCEL_ON_SET, &timerSet, NULL) != 0)
261 {
262 LOGE("suspend timer cancel fail");
263 }
264
265 pthread_detach(g_timer_thread_id);
266
267 pthread_cancel(g_timer_thread_id);
268
269 result = epoll_ctl(g_mEpollFd, EPOLL_CTL_DEL, g_sleep_timer_fd, &eventItem);
270 if (result != 0)
271 {
272 LOGE("Could not del timer fd(%d) to epoll instance: %s\n", g_sleep_timer_fd, strerror(errno));
273 }
274
275 close(g_sleep_timer_fd);
liuyang34770f82024-11-14 17:26:24 +0800276 }
liuyang83375062024-11-22 17:49:49 +0800277
278 g_mEpollFd = epoll_create(EPOLL_SIZE_HINT);
b.liuacb8b4a2024-11-19 15:50:11 +0800279
liuyang34770f82024-11-14 17:26:24 +0800280 g_sleep_timer_fd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0);
281 if (g_sleep_timer_fd < 0) {
282 LOGE("Could not create timer fd: %s\n", strerror(errno));
283 return 0;
284 }
b.liuacb8b4a2024-11-19 15:50:11 +0800285
liuyang34770f82024-11-14 17:26:24 +0800286 timerSet.it_interval.tv_sec = 0;
287 timerSet.it_interval.tv_nsec = 0;
288 timerSet.it_value.tv_sec = time;
289 timerSet.it_value.tv_nsec = 0;
290 if (timerfd_settime(g_sleep_timer_fd, 0, &timerSet, NULL) != 0) {
291 LOGE("timerfd_settime failed: %s\n", strerror(errno));
292 close(g_sleep_timer_fd);
293 return 0;
294 }
b.liuacb8b4a2024-11-19 15:50:11 +0800295
liuyang83375062024-11-22 17:49:49 +0800296
liuyang34770f82024-11-14 17:26:24 +0800297 memset(&eventItem, 0, sizeof(eventItem));
298 eventItem.events = EPOLLIN | EPOLLET;
299 eventItem.data.fd = g_sleep_timer_fd;
liuyang83375062024-11-22 17:49:49 +0800300 result = epoll_ctl(g_mEpollFd, EPOLL_CTL_ADD, g_sleep_timer_fd, &eventItem);
liuyang34770f82024-11-14 17:26:24 +0800301 if (result != 0) {
302 LOGE("Could not add timer fd(%d) to epoll instance: %s\n", g_sleep_timer_fd, strerror(errno));
303 }
304
305 mbtk_autosuspend_enable(1);
306 g_sleep_timer_cb = cb;
307 suspend_timer_timer_init();
308
309
310 return 0;
311}
312
313
r.xiao27072552024-10-24 01:02:48 -0700314
315