3
* oFono - Open Source Telephony - Android based wakelocks
5
* Copyright (C) 2016 Canonical Ltd.
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
#include <sys/types.h>
38
#define OFONO_API_SUBJECT_TO_CHANGE
44
#define ANDROID_WAKELOCK_LOCK_PATH "/sys/power/wake_lock"
45
#define ANDROID_WAKELOCK_UNLOCK_PATH "/sys/power/wake_unlock"
49
unsigned int acquisitions;
54
static int file_exists(char const *filename)
58
return stat(filename, &st) == 0;
61
static int write_file(const char *file, const char *content)
66
fd = open(file, O_WRONLY);
71
r = write(fd, content, strlen(content));
75
if (r != strlen(content))
81
static int wakelock_lock(const char *name)
83
return write_file(ANDROID_WAKELOCK_LOCK_PATH, name);
86
static int wakelock_unlock(const char *name)
88
return write_file(ANDROID_WAKELOCK_UNLOCK_PATH, name);
91
static int android_wakelock_acquire(struct wakelock *lock)
96
if (lock->acquisitions > 0) {
101
if (wakelock_lock(lock->name) < 0)
104
lock->acquisitions++;
109
static int android_wakelock_release(struct wakelock *lock)
114
DBG("lock %p name %s acquisitions %d",
115
lock, lock->name, lock->acquisitions);
117
if (!lock->acquisitions) {
118
ofono_warn("Attempted to release already released lock %s", lock->name);
122
if (lock->acquisitions > 1) {
123
lock->acquisitions--;
124
DBG("lock %s released acquisitions %d", lock->name, lock->acquisitions);
128
if (wakelock_unlock(lock->name) < 0)
131
lock->acquisitions = 0;
133
DBG("lock %s was released", lock->name);
138
static int android_wakelock_create(const char *name, struct wakelock **lock)
143
*lock = g_new0(struct wakelock, 1);
144
(*lock)->name = g_strdup(name);
145
(*lock)->acquisitions = 0;
147
locks = g_slist_prepend(locks, *lock);
149
DBG("wakelock %s create", name);
154
static int android_wakelock_free(struct wakelock *lock)
159
if (lock->acquisitions) {
160
/* Need to force releasing the lock here */
161
lock->acquisitions = 1;
162
android_wakelock_release(lock);
165
locks = g_slist_remove(locks, lock);
167
DBG("Freeing lock %s", lock->name);
175
static ofono_bool_t android_wakelock_is_locked(struct wakelock *lock)
180
return lock->acquisitions > 0;
183
struct wakelock_table driver = {
184
.create = android_wakelock_create,
185
.free = android_wakelock_free,
186
.acquire = android_wakelock_acquire,
187
.release = android_wakelock_release,
188
.is_locked = android_wakelock_is_locked
191
static int android_wakelock_init(void)
193
if (!file_exists(ANDROID_WAKELOCK_LOCK_PATH)) {
194
ofono_warn("System does not support Android wakelocks.");
198
if (wakelock_plugin_register("android-wakelock", &driver) < 0) {
199
ofono_error("Failed to register wakelock driver");
206
static void android_wakelock_exit(void)
208
wakelock_plugin_unregister();
211
OFONO_PLUGIN_DEFINE(android_wakelock, "Android Wakelock driver", VERSION,
212
OFONO_PLUGIN_PRIORITY_DEFAULT, android_wakelock_init, android_wakelock_exit)