4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include "device-notifier.h"
24 #include "shared/common.h"
25 #include <libsyscommon/list.h>
27 #define __stringify_1(x...) #x
28 #define __stringify(x...) __stringify_1(x)
30 struct device_notifier {
32 int priority; /* descending order */
35 enum device_notifier_type type;
36 int (*func)(void *data);
38 int (*func_udata)(void *data, void *user_data);
39 void (*destroyer)(void *user_data);
43 static GList *device_notifier_list;
46 #define FIND_NOTIFIER(a, b, d, e, f) \
47 SYS_G_LIST_FOREACH(a, b, d) \
48 if (e == d->e && f == (d->f))
50 #define NOTIFY_STR(x) [(x)] = __stringify((x))
52 static const char *device_notifier_type_str[DEVICE_NOTIFIER_MAX] = {
53 NOTIFY_STR(DEVICE_NOTIFIER_DAEMON_RESTARTED),
54 NOTIFY_STR(DEVICE_NOTIFIER_DELAYED_INIT),
55 NOTIFY_STR(DEVICE_NOTIFIER_LCD),
56 NOTIFY_STR(DEVICE_NOTIFIER_LCD_OFF),
57 NOTIFY_STR(DEVICE_NOTIFIER_LCD_OFF_COMPLETE),
58 NOTIFY_STR(DEVICE_NOTIFIER_LCD_AUTOBRT_SENSING),
59 NOTIFY_STR(DEVICE_NOTIFIER_LOWBAT),
60 NOTIFY_STR(DEVICE_NOTIFIER_FULLBAT),
61 NOTIFY_STR(DEVICE_NOTIFIER_POWER_SUPPLY),
62 NOTIFY_STR(DEVICE_NOTIFIER_BATTERY_HEALTH),
63 NOTIFY_STR(DEVICE_NOTIFIER_BATTERY_PRESENT),
64 NOTIFY_STR(DEVICE_NOTIFIER_BATTERY_OVP),
65 NOTIFY_STR(DEVICE_NOTIFIER_BATTERY_CHARGING),
66 NOTIFY_STR(DEVICE_NOTIFIER_BATTERY_CHARGER_CONNECTED),
67 NOTIFY_STR(DEVICE_NOTIFIER_BATTERY_CHARGER_DISCONNECTED),
68 NOTIFY_STR(DEVICE_NOTIFIER_DISPLAY_AMBIENT_CONDITION),
69 NOTIFY_STR(DEVICE_NOTIFIER_DISPLAY_AMBIENT_STATE),
70 NOTIFY_STR(DEVICE_NOTIFIER_DISPLAY_LOCK),
71 NOTIFY_STR(DEVICE_NOTIFIER_POWER_RESUME),
72 NOTIFY_STR(DEVICE_NOTIFIER_POWEROFF),
73 NOTIFY_STR(DEVICE_NOTIFIER_APPLICATION_BACKGROUND),
74 NOTIFY_STR(DEVICE_NOTIFIER_APPLICATION_FOREGROUND),
75 NOTIFY_STR(DEVICE_NOTIFIER_APPLICATION_TERMINATED),
76 NOTIFY_STR(DEVICE_NOTIFIER_USB_DEBUG_MODE),
77 NOTIFY_STR(DEVICE_NOTIFIER_USB_TETHERING_MODE),
78 NOTIFY_STR(DEVICE_NOTIFIER_EVENT_HANDLER),
79 NOTIFY_STR(DEVICE_NOTIFIER_CPU_BOOST_LOWBAT),
80 NOTIFY_STR(DEVICE_NOTIFIER_CPU_BOOST_POWEROFF),
81 NOTIFY_STR(DEVICE_NOTIFIER_PMQOS),
82 NOTIFY_STR(DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING),
83 NOTIFY_STR(DEVICE_NOTIFIER_PMQOS_POWERSAVING),
84 NOTIFY_STR(DEVICE_NOTIFIER_COOL_DOWN),
85 NOTIFY_STR(DEVICE_NOTIFIER_VITAL_STATE),
86 NOTIFY_STR(DEVICE_NOTIFIER_LONGKEY_RESTORE),
87 NOTIFY_STR(DEVICE_NOTIFIER_UPSM),
88 NOTIFY_STR(DEVICE_NOTIFIER_UPSM_OFF),
89 NOTIFY_STR(DEVICE_NOTIFIER_BEZEL_WAKEUP),
90 NOTIFY_STR(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS),
91 NOTIFY_STR(DEVICE_NOTIFIER_ULTRAPOWERSAVING),
92 NOTIFY_STR(DEVICE_NOTIFIER_EXTCON_COUNT),
93 NOTIFY_STR(DEVICE_NOTIFIER_KEY_PRESS),
94 NOTIFY_STR(DEVICE_NOTIFIER_KEY_RELEASE),
96 /* action triggered by input event */
97 NOTIFY_STR(DEVICE_NOTIFIER_INPUT_TRIGGER_POWEROFF),
98 NOTIFY_STR(DEVICE_NOTIFIER_INPUT_BROADCAST_SIGNAL),
100 /* Purpose of calling methods of different modules
101 * Use prefix DEVICE_NOTIFIER_REQUEST */
102 NOTIFY_STR(DEVICE_NOTIFIER_REQUEST_TRANSITION_STATE),
105 static gint compare_priority(gconstpointer a, gconstpointer b)
107 /* descending order */
108 return ((const struct device_notifier *)b)->priority - ((const struct device_notifier *)a)->priority + 1;
111 int __register_notifier(enum device_notifier_type type, notify_cb func, int priority, const char *caller)
114 struct device_notifier *notifier;
116 if (type < DEVICE_NOTIFIER_MIN || type >= DEVICE_NOTIFIER_MAX)
119 _I("%s, %p by %s", device_notifier_type_str[type], func, caller);
122 _E("invalid func address! by %s", caller);
126 FIND_NOTIFIER(device_notifier_list, n, notifier, type, func) {
127 _E("function is already registered! [%s, %p] by %s",
128 device_notifier_type_str[type], func, caller);
132 notifier = calloc(1, sizeof(struct device_notifier));
134 _E("Fail to malloc for %s notifier! by %s", device_notifier_type_str[type], caller);
138 notifier->type = type;
139 notifier->priority = priority;
140 notifier->func = func;
142 device_notifier_list = g_list_insert_sorted(device_notifier_list, notifier, compare_priority);
147 int __register_notifier_udata(enum device_notifier_type type,
148 notify_cb_udata func_udata, void *user_data,
149 destroy_cb_udata func_destroy_udata, int priority, const char *caller)
151 struct device_notifier *notifier;
154 if (type < DEVICE_NOTIFIER_MIN || type >= DEVICE_NOTIFIER_MAX)
157 _I("%s, %p by %s", device_notifier_type_str[type], func_udata, caller);
160 _E("invalid func address! by %s", caller);
164 notifier = calloc(1, sizeof(struct device_notifier));
166 _E("Fail to malloc for %s notifier! by %s", device_notifier_type_str[type], caller);
171 notifier->priority = priority;
172 notifier->type = type;
173 notifier->func_udata = func_udata;
174 notifier->user_data = user_data;
175 notifier->destroyer = func_destroy_udata;
177 device_notifier_list = g_list_insert_sorted(device_notifier_list, notifier, compare_priority);
184 int __unregister_notifier(enum device_notifier_type type, notify_cb func, const char *caller)
187 struct device_notifier *notifier;
189 if (type < DEVICE_NOTIFIER_MIN || type >= DEVICE_NOTIFIER_MAX)
193 _E("invalid func address of %s! by %s", device_notifier_type_str[type], caller);
197 FIND_NOTIFIER(device_notifier_list, n, notifier, type, func) {
198 _I("[%s, %p] by %s", device_notifier_type_str[type], func, caller);
199 notifier->deleted = true;
205 int __unregister_notifier_udata(int id, const char *caller)
208 struct device_notifier *notifier;
210 SYS_G_LIST_FOREACH(device_notifier_list, n, notifier) {
211 if (notifier->id == id) {
212 if (notifier->destroyer)
213 notifier->destroyer(notifier->user_data);
214 notifier->deleted = true;
221 static gboolean delete_unused_notifier_cb(void *data)
225 struct device_notifier *notifier;
227 SYS_G_LIST_FOREACH_SAFE(device_notifier_list, n, next, notifier) {
228 if (notifier->deleted) {
229 SYS_G_LIST_REMOVE_LIST(device_notifier_list, n);
235 return G_SOURCE_REMOVE;
238 void device_notify(enum device_notifier_type type, void *data)
241 struct device_notifier *notifier;
243 SYS_G_LIST_FOREACH(device_notifier_list, n, notifier) {
244 if (!notifier->deleted && type == notifier->type) {
246 notifier->func(data);
247 else if (notifier->func_udata)
248 notifier->func_udata(data, notifier->user_data);
253 idl = g_idle_add(delete_unused_notifier_cb, NULL);
256 void device_notify_once(enum device_notifier_type type, void *data)
259 struct device_notifier *notifier;
261 SYS_G_LIST_FOREACH(device_notifier_list, n, notifier) {
262 if (!notifier->deleted && type == notifier->type) {
263 if (notifier->func) {
264 notifier->func(data);
265 } else if (notifier->func_udata) {
266 notifier->func_udata(data, notifier->user_data);
267 if (notifier->destroyer)
268 notifier->destroyer(notifier->user_data);
271 notifier->deleted = true;
276 idl = g_idle_add(delete_unused_notifier_cb, NULL);