~phablet-team/ofono/pro5-support-and-more

« back to all changes in this revision

Viewing changes to plugins/android-wakelock.c

  • Committer: Alfonso Sanchez-Beato
  • Date: 2016-03-14 08:16:40 UTC
  • mfrom: (6830.1.193)
  • Revision ID: alfonso.sanchez-beato@canonical.com-20160314081640-6gheyv347h1g25nu
[ Tony Espy ]
* unit: new rilmodem tests for sms and call barring
* plugins: address upower plugin upstream comments
* unit: fix test-grilreply set_facility_lock test
* style fixes for wakelock support
[ Ratchanan Srirattanamet ]
* qcommsimmodem: fix setting 3G pref when one of the slots is empty
[ Alfonso Sanchez-Beato ]
* ril: set properly gril vendor
* support for system settings
* unit: make tests parallelizable
[ Vicamo Yang ]
* ril, gril: support for pro 5
* gril, rilmodem: set RIL version from CONNECTED event
* unit: fix warning

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  oFono - Open Source Telephony - Android based wakelocks
 
4
 *
 
5
 *  Copyright (C) 2016 Canonical Ltd.
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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
 
20
 *
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include <config.h>
 
25
#endif
 
26
 
 
27
#include <sys/types.h>
 
28
#include <sys/stat.h>
 
29
#include <fcntl.h>
 
30
#include <unistd.h>
 
31
#include <string.h>
 
32
#include <errno.h>
 
33
#include <glib.h>
 
34
#include <dlfcn.h>
 
35
 
 
36
#include <glib.h>
 
37
 
 
38
#define OFONO_API_SUBJECT_TO_CHANGE
 
39
 
 
40
#include "plugin.h"
 
41
#include "log.h"
 
42
#include "wakelock.h"
 
43
 
 
44
#define ANDROID_WAKELOCK_LOCK_PATH              "/sys/power/wake_lock"
 
45
#define ANDROID_WAKELOCK_UNLOCK_PATH    "/sys/power/wake_unlock"
 
46
 
 
47
struct wakelock {
 
48
        char *name;
 
49
        unsigned int acquisitions;
 
50
};
 
51
 
 
52
GSList *locks = NULL;
 
53
 
 
54
static int file_exists(char const *filename)
 
55
{
 
56
        struct stat st;
 
57
 
 
58
        return stat(filename, &st) == 0;
 
59
}
 
60
 
 
61
static int write_file(const char *file, const char *content)
 
62
{
 
63
        int fd;
 
64
        unsigned int r = 0;
 
65
 
 
66
        fd = open(file, O_WRONLY);
 
67
 
 
68
        if (fd == -1)
 
69
                return -EIO;
 
70
 
 
71
        r = write(fd, content, strlen(content));
 
72
 
 
73
        close(fd);
 
74
 
 
75
        if (r != strlen(content))
 
76
                return -EIO;
 
77
 
 
78
        return 0;
 
79
}
 
80
 
 
81
static int wakelock_lock(const char *name)
 
82
{
 
83
        return write_file(ANDROID_WAKELOCK_LOCK_PATH, name);
 
84
}
 
85
 
 
86
static int wakelock_unlock(const char *name)
 
87
{
 
88
        return write_file(ANDROID_WAKELOCK_UNLOCK_PATH, name);
 
89
}
 
90
 
 
91
static int android_wakelock_acquire(struct wakelock *lock)
 
92
{
 
93
        if (lock == NULL)
 
94
                return -EINVAL;
 
95
 
 
96
        if (lock->acquisitions > 0) {
 
97
                lock->acquisitions++;
 
98
                return 0;
 
99
        }
 
100
 
 
101
        if (wakelock_lock(lock->name) < 0)
 
102
                return -EIO;
 
103
 
 
104
        lock->acquisitions++;
 
105
 
 
106
        return 0;
 
107
}
 
108
 
 
109
static int android_wakelock_release(struct wakelock *lock)
 
110
{
 
111
        if (lock == NULL)
 
112
                return -EINVAL;
 
113
 
 
114
        DBG("lock %p name %s acquisitions %d",
 
115
                lock, lock->name, lock->acquisitions);
 
116
 
 
117
        if (!lock->acquisitions) {
 
118
                ofono_warn("Attempted to release already released lock %s", lock->name);
 
119
                return -EINVAL;
 
120
        }
 
121
 
 
122
        if (lock->acquisitions > 1) {
 
123
                lock->acquisitions--;
 
124
                DBG("lock %s released acquisitions %d", lock->name, lock->acquisitions);
 
125
                return 0;
 
126
        }
 
127
 
 
128
        if (wakelock_unlock(lock->name) < 0)
 
129
                return -EIO;
 
130
 
 
131
        lock->acquisitions = 0;
 
132
 
 
133
        DBG("lock %s was released", lock->name);
 
134
 
 
135
        return 0;
 
136
}
 
137
 
 
138
static int android_wakelock_create(const char *name, struct wakelock **lock)
 
139
{
 
140
        if (lock == NULL)
 
141
                return -EINVAL;
 
142
 
 
143
        *lock = g_new0(struct wakelock, 1);
 
144
        (*lock)->name = g_strdup(name);
 
145
        (*lock)->acquisitions = 0;
 
146
 
 
147
        locks = g_slist_prepend(locks, *lock);
 
148
 
 
149
        DBG("wakelock %s create", name);
 
150
 
 
151
        return 0;
 
152
}
 
153
 
 
154
static int android_wakelock_free(struct wakelock *lock)
 
155
{
 
156
        if (lock == NULL)
 
157
                return -EINVAL;
 
158
 
 
159
        if (lock->acquisitions) {
 
160
                /* Need to force releasing the lock here */
 
161
                lock->acquisitions = 1;
 
162
                android_wakelock_release(lock);
 
163
        }
 
164
 
 
165
        locks = g_slist_remove(locks, lock);
 
166
 
 
167
        DBG("Freeing lock %s", lock->name);
 
168
 
 
169
        g_free(lock->name);
 
170
        g_free(lock);
 
171
 
 
172
        return 0;
 
173
}
 
174
 
 
175
static ofono_bool_t android_wakelock_is_locked(struct wakelock *lock)
 
176
{
 
177
        if (lock == NULL)
 
178
                return FALSE;
 
179
 
 
180
        return lock->acquisitions > 0;
 
181
}
 
182
 
 
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
 
189
};
 
190
 
 
191
static int android_wakelock_init(void)
 
192
{
 
193
        if (!file_exists(ANDROID_WAKELOCK_LOCK_PATH)) {
 
194
                ofono_warn("System does not support Android wakelocks.");
 
195
                return 0;
 
196
        }
 
197
 
 
198
        if (wakelock_plugin_register("android-wakelock", &driver) < 0) {
 
199
                ofono_error("Failed to register wakelock driver");
 
200
                return -EIO;
 
201
        }
 
202
 
 
203
        return 0;
 
204
}
 
205
 
 
206
static void android_wakelock_exit(void)
 
207
{
 
208
        wakelock_plugin_unregister();
 
209
}
 
210
 
 
211
OFONO_PLUGIN_DEFINE(android_wakelock, "Android Wakelock driver", VERSION,
 
212
                        OFONO_PLUGIN_PRIORITY_DEFAULT, android_wakelock_init, android_wakelock_exit)