4 * Copyright (c) 2022 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.
21 #include <linux/input.h>
22 #include <libsyscommon/ini-parser.h>
23 #include <libsyscommon/bitmap.h>
24 #include <libsyscommon/file.h>
26 #include "shared/device-notifier.h"
27 #include "shared/log.h"
28 #include "power-event-lock.h"
30 #define BATTERY_CONF_FILE "/etc/deviced/battery.conf"
32 /* eventlock is another wakelock than mainlock.
34 * The eventlock works independently of mainlock, which is controlled by
35 * power state. The main purpose of eventlock is to prevent the subroutine
36 * of an event from going to sleep regardless of the power state. */
37 #define EVENT_LOCK "eventlock"
39 static struct syscommon_bitmap *eventlock;
40 static int notifier_id[EL_MAX][2];
42 void event_wake_lock(enum eventlock_type type)
46 if (type <= EL_MIN || type >= EL_MAX)
49 syscommon_bitmap_set_bit(eventlock, type);
50 setcount = syscommon_bitmap_count_set_bit(eventlock);
52 _I("Set eventlock of type=%d, current number of eventlock=%d", type, setcount);
55 sys_set_str("/sys/power/wake_lock", EVENT_LOCK);
56 _I("Acquired eventlock");
60 void event_wake_unlock(enum eventlock_type type)
64 if (type <= EL_MIN || type >= EL_MAX)
67 syscommon_bitmap_clear_bit(eventlock, type);
68 setcount = syscommon_bitmap_count_set_bit(eventlock);
70 _I("Unset eventlock of type=%d, current number of eventlock=%d", type, setcount);
73 sys_set_str("/sys/power/wake_unlock", EVENT_LOCK);
74 _I("Released eventlock");
78 static enum eventlock_type expand_key_eventlock_type(int keycode)
80 if (keycode == KEY_POWER)
82 if (keycode == KEY_BLUETOOTH)
83 return EL_KEY_BLUETOOTH;
84 /* add mapping for keycode to eventlock_type here */
89 static int power_event_lock_callback(void *data, void *udata)
91 enum eventlock_type type = (enum eventlock_type)(intptr_t) udata;
94 /* On receiving key event, expand EL_KEY to EL_KEY_* according to the keycode */
95 int keycode = (int)(intptr_t) data;
96 type = expand_key_eventlock_type(keycode);
99 event_wake_lock(type);
104 static int power_event_unlock_callback(void *data, void *udata)
106 enum eventlock_type type = (enum eventlock_type)(intptr_t) udata;
108 if (type == EL_KEY) {
109 /* On receiving key event, expand EL_KEY to EL_KEY_* according to the keycode */
110 int keycode = (int)(intptr_t) data;
111 type = expand_key_eventlock_type(keycode);
114 event_wake_unlock(type);
119 static void register_power_event_lock_controller(enum eventlock_type type,
120 enum deviced_notifier lock_notify,
121 enum deviced_notifier unlock_notify)
123 /* Acquiring lock must be followed by all the other notifiers, therefore
124 * give a large enough number as priority to make it be at the head of notifier list.
125 * On the other hand, releasing lock must follow all the other notifiers, therefore
126 * give a small enough number as priority to make it be at the tail of notifier list. */
127 notifier_id[type][0] = syscommon_notifier_subscribe_notify_udata_priority(lock_notify,
128 power_event_lock_callback, (void *)(intptr_t) type, NULL, 1000);
129 notifier_id[type][1] = syscommon_notifier_subscribe_notify_udata_priority(unlock_notify,
130 power_event_unlock_callback, (void *)(intptr_t) type, NULL, -1000);
133 static int check_charger_wakelock(struct parse_result *result, void *user_data)
135 if (MATCH(result->section, "ChargerWakelock")
136 && MATCH(result->name, "ChargerWakeLockEnabled")
137 && MATCH(result->value, "yes"))
138 *(int *) user_data = 1;
143 void power_event_lock_init(void)
145 int charger_wakelock = 0;
147 eventlock = syscommon_bitmap_init_bitmap(EL_MAX);
149 _E("Failed to init event lock bitmap");
153 config_parse(BATTERY_CONF_FILE, check_charger_wakelock, &charger_wakelock);
155 /* general events, mostly defined by configuration file */
156 register_power_event_lock_controller(EL_EVENT_ACTION,
157 DEVICED_NOTIFIER_EVENT_ACQUIRE_WAKELOCK,
158 DEVICED_NOTIFIER_EVENT_RELEASE_WAKELOCK);
160 /* key input event */
161 register_power_event_lock_controller(EL_KEY,
162 DEVICED_NOTIFIER_KEY_PRESS,
163 DEVICED_NOTIFIER_KEY_RELEASE);
166 if (charger_wakelock) {
167 register_power_event_lock_controller(EL_CHARGER,
168 DEVICED_NOTIFIER_BATTERY_CHARGER_CONNECTED,
169 DEVICED_NOTIFIER_BATTERY_CHARGER_DISCONNECTED);