1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <sys/ioctl.h>
6 #include <unistd.h>
7 
8 #include "sd-messages.h"
9 
10 #include "alloc-util.h"
11 #include "async.h"
12 #include "fd-util.h"
13 #include "logind-button.h"
14 #include "missing_input.h"
15 #include "string-util.h"
16 #include "util.h"
17 
18 #define CONST_MAX5(a, b, c, d, e) CONST_MAX(CONST_MAX(a, b), CONST_MAX(CONST_MAX(c, d), e))
19 
20 #define ULONG_BITS (sizeof(unsigned long)*8)
21 
22 #define LONG_PRESS_DURATION (5 * USEC_PER_SEC)
23 
bitset_get(const unsigned long * bits,unsigned i)24 static bool bitset_get(const unsigned long *bits, unsigned i) {
25         return (bits[i / ULONG_BITS] >> (i % ULONG_BITS)) & 1UL;
26 }
27 
bitset_put(unsigned long * bits,unsigned i)28 static void bitset_put(unsigned long *bits, unsigned i) {
29         bits[i / ULONG_BITS] |= (unsigned long) 1 << (i % ULONG_BITS);
30 }
31 
button_new(Manager * m,const char * name)32 Button* button_new(Manager *m, const char *name) {
33         Button *b;
34 
35         assert(m);
36         assert(name);
37 
38         b = new0(Button, 1);
39         if (!b)
40                 return NULL;
41 
42         b->name = strdup(name);
43         if (!b->name)
44                 return mfree(b);
45 
46         if (hashmap_put(m->buttons, b->name, b) < 0) {
47                 free(b->name);
48                 return mfree(b);
49         }
50 
51         b->manager = m;
52         b->fd = -1;
53 
54         return b;
55 }
56 
button_free(Button * b)57 void button_free(Button *b) {
58         assert(b);
59 
60         hashmap_remove(b->manager->buttons, b->name);
61 
62         sd_event_source_unref(b->io_event_source);
63         sd_event_source_unref(b->check_event_source);
64 
65         asynchronous_close(b->fd);
66 
67         free(b->name);
68         free(b->seat);
69         free(b);
70 }
71 
button_set_seat(Button * b,const char * sn)72 int button_set_seat(Button *b, const char *sn) {
73         assert(b);
74 
75         return free_and_strdup(&b->seat, sn);
76 }
77 
button_lid_switch_handle_action(Manager * manager,bool is_edge)78 static void button_lid_switch_handle_action(Manager *manager, bool is_edge) {
79         HandleAction handle_action;
80 
81         assert(manager);
82 
83         /* If we are docked or on external power, handle the lid switch
84          * differently */
85         if (manager_is_docked_or_external_displays(manager))
86                 handle_action = manager->handle_lid_switch_docked;
87         else if (handle_action_valid(manager->handle_lid_switch_ep) && manager_is_on_external_power())
88                 handle_action = manager->handle_lid_switch_ep;
89         else
90                 handle_action = manager->handle_lid_switch;
91 
92         manager_handle_action(manager, INHIBIT_HANDLE_LID_SWITCH, handle_action, manager->lid_switch_ignore_inhibited, is_edge);
93 }
94 
button_recheck(sd_event_source * e,void * userdata)95 static int button_recheck(sd_event_source *e, void *userdata) {
96         Button *b = userdata;
97 
98         assert(b);
99         assert(b->lid_closed);
100 
101         button_lid_switch_handle_action(b->manager, false);
102         return 1;
103 }
104 
button_install_check_event_source(Button * b)105 static int button_install_check_event_source(Button *b) {
106         int r;
107         assert(b);
108 
109         /* Install a post handler, so that we keep rechecking as long as the lid is closed. */
110 
111         if (b->check_event_source)
112                 return 0;
113 
114         r = sd_event_add_post(b->manager->event, &b->check_event_source, button_recheck, b);
115         if (r < 0)
116                 return r;
117 
118         return sd_event_source_set_priority(b->check_event_source, SD_EVENT_PRIORITY_IDLE+1);
119 }
120 
long_press_of_power_key_handler(sd_event_source * e,uint64_t usec,void * userdata)121 static int long_press_of_power_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
122         Manager *m = userdata;
123 
124         assert(e);
125         assert(m);
126 
127         m->power_key_long_press_event_source = sd_event_source_unref(m->power_key_long_press_event_source);
128 
129         log_struct(LOG_INFO,
130                    LOG_MESSAGE("Power key pressed long."),
131                    "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_LONG_PRESS_STR);
132 
133         manager_handle_action(m, INHIBIT_HANDLE_POWER_KEY, m->handle_power_key_long_press, m->power_key_ignore_inhibited, true);
134         return 0;
135 }
136 
long_press_of_reboot_key_handler(sd_event_source * e,uint64_t usec,void * userdata)137 static int long_press_of_reboot_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
138         Manager *m = userdata;
139 
140         assert(e);
141         assert(m);
142 
143         m->reboot_key_long_press_event_source = sd_event_source_unref(m->reboot_key_long_press_event_source);
144 
145         log_struct(LOG_INFO,
146                    LOG_MESSAGE("Reboot key pressed long."),
147                    "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_LONG_PRESS_STR);
148 
149         manager_handle_action(m, INHIBIT_HANDLE_REBOOT_KEY, m->handle_reboot_key_long_press, m->reboot_key_ignore_inhibited, true);
150         return 0;
151 }
152 
long_press_of_suspend_key_handler(sd_event_source * e,uint64_t usec,void * userdata)153 static int long_press_of_suspend_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
154         Manager *m = userdata;
155 
156         assert(e);
157         assert(m);
158 
159         m->suspend_key_long_press_event_source = sd_event_source_unref(m->suspend_key_long_press_event_source);
160 
161         log_struct(LOG_INFO,
162                    LOG_MESSAGE("Suspend key pressed long."),
163                    "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_LONG_PRESS_STR);
164 
165         manager_handle_action(m, INHIBIT_HANDLE_SUSPEND_KEY, m->handle_suspend_key_long_press, m->suspend_key_ignore_inhibited, true);
166         return 0;
167 }
168 
long_press_of_hibernate_key_handler(sd_event_source * e,uint64_t usec,void * userdata)169 static int long_press_of_hibernate_key_handler(sd_event_source *e, uint64_t usec, void *userdata) {
170         Manager *m = userdata;
171 
172         assert(e);
173         assert(m);
174 
175         m->hibernate_key_long_press_event_source = sd_event_source_unref(m->hibernate_key_long_press_event_source);
176 
177         log_struct(LOG_INFO,
178                    LOG_MESSAGE("Hibernate key pressed long."),
179                    "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS_STR);
180 
181         manager_handle_action(m, INHIBIT_HANDLE_HIBERNATE_KEY, m->handle_hibernate_key_long_press, m->hibernate_key_ignore_inhibited, true);
182         return 0;
183 }
184 
start_long_press(Manager * m,sd_event_source ** e,sd_event_time_handler_t callback)185 static void start_long_press(Manager *m, sd_event_source **e, sd_event_time_handler_t callback) {
186         int r;
187 
188         assert(m);
189         assert(e);
190 
191         if (*e)
192                 return;
193 
194         r = sd_event_add_time_relative(
195                         m->event,
196                         e,
197                         CLOCK_MONOTONIC,
198                         LONG_PRESS_DURATION, 0,
199                         callback, m);
200         if (r < 0)
201                 log_warning_errno(r, "Failed to add long press timer event, ignoring: %m");
202 }
203 
button_dispatch(sd_event_source * s,int fd,uint32_t revents,void * userdata)204 static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
205         Button *b = userdata;
206         struct input_event ev;
207         ssize_t l;
208 
209         assert(s);
210         assert(fd == b->fd);
211         assert(b);
212 
213         l = read(b->fd, &ev, sizeof(ev));
214         if (l < 0)
215                 return errno != EAGAIN ? -errno : 0;
216         if ((size_t) l < sizeof(ev))
217                 return -EIO;
218 
219         if (ev.type == EV_KEY && ev.value > 0) {
220 
221                 switch (ev.code) {
222 
223                 case KEY_POWER:
224                 case KEY_POWER2:
225                         if (b->manager->handle_power_key_long_press != HANDLE_IGNORE && b->manager->handle_power_key_long_press != b->manager->handle_power_key) {
226                                 log_debug("Power key pressed. Further action depends on the key press duration.");
227                                 start_long_press(b->manager, &b->manager->power_key_long_press_event_source, long_press_of_power_key_handler);
228                         } else {
229                                 log_struct(LOG_INFO,
230                                            LOG_MESSAGE("Power key pressed short."),
231                                            "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR);
232                                 manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
233                         }
234                         break;
235 
236                 /* The kernel naming is a bit confusing here:
237                    KEY_RESTART was probably introduced for media playback purposes, but
238                    is now being predominantly used to indicate device reboot.
239                 */
240 
241                 case KEY_RESTART:
242                         if (b->manager->handle_reboot_key_long_press != HANDLE_IGNORE && b->manager->handle_reboot_key_long_press != b->manager->handle_reboot_key) {
243                                 log_debug("Reboot key pressed. Further action depends on the key press duration.");
244                                 start_long_press(b->manager, &b->manager->reboot_key_long_press_event_source, long_press_of_reboot_key_handler);
245                         } else {
246                                 log_struct(LOG_INFO,
247                                            LOG_MESSAGE("Reboot key pressed short."),
248                                            "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
249                                 manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
250                         }
251                         break;
252 
253                 /* The kernel naming is a bit confusing here:
254 
255                    KEY_SLEEP   = suspend-to-ram, which everybody else calls "suspend"
256                    KEY_SUSPEND = suspend-to-disk, which everybody else calls "hibernate"
257                 */
258 
259                 case KEY_SLEEP:
260                         if (b->manager->handle_suspend_key_long_press != HANDLE_IGNORE && b->manager->handle_suspend_key_long_press != b->manager->handle_suspend_key) {
261                                 log_debug("Suspend key pressed. Further action depends on the key press duration.");
262                                 start_long_press(b->manager, &b->manager->suspend_key_long_press_event_source, long_press_of_suspend_key_handler);
263                         } else {
264                                 log_struct(LOG_INFO,
265                                            LOG_MESSAGE("Suspend key pressed short."),
266                                            "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR);
267                                 manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
268                         }
269                         break;
270 
271                 case KEY_SUSPEND:
272                         if (b->manager->handle_hibernate_key_long_press != HANDLE_IGNORE && b->manager->handle_hibernate_key_long_press != b->manager->handle_hibernate_key) {
273                                 log_debug("Hibernate key pressed. Further action depends on the key press duration.");
274                                 start_long_press(b->manager, &b->manager->hibernate_key_long_press_event_source, long_press_of_hibernate_key_handler);
275                         } else {
276                                 log_struct(LOG_INFO,
277                                            LOG_MESSAGE("Hibernate key pressed short."),
278                                            "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR);
279                                 manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
280                         }
281                         break;
282                 }
283 
284         } else if (ev.type == EV_KEY && ev.value == 0) {
285 
286                 switch (ev.code) {
287 
288                 case KEY_POWER:
289                 case KEY_POWER2:
290                         if (b->manager->power_key_long_press_event_source) {
291                                 /* Long press event timer is still pending and key release
292                                    event happened.  This means that key press duration was
293                                    insufficient to trigger a long press event
294                                 */
295                                 log_struct(LOG_INFO,
296                                            LOG_MESSAGE("Power key pressed short."),
297                                            "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR);
298 
299                                 b->manager->power_key_long_press_event_source = sd_event_source_unref(b->manager->power_key_long_press_event_source);
300 
301                                 manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
302                         }
303                         break;
304 
305                 case KEY_RESTART:
306                         if (b->manager->reboot_key_long_press_event_source) {
307                                 log_struct(LOG_INFO,
308                                            LOG_MESSAGE("Reboot key pressed short."),
309                                            "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
310 
311                                 b->manager->reboot_key_long_press_event_source = sd_event_source_unref(b->manager->reboot_key_long_press_event_source);
312 
313                                 manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
314                         }
315                         break;
316 
317                 case KEY_SLEEP:
318                         if (b->manager->suspend_key_long_press_event_source) {
319                                 log_struct(LOG_INFO,
320                                            LOG_MESSAGE("Suspend key pressed short."),
321                                            "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR);
322 
323                                 b->manager->suspend_key_long_press_event_source = sd_event_source_unref(b->manager->suspend_key_long_press_event_source);
324 
325                                 manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
326                         }
327                         break;
328                 case KEY_SUSPEND:
329                         if (b->manager->hibernate_key_long_press_event_source) {
330                                 log_struct(LOG_INFO,
331                                            LOG_MESSAGE("Hibernate key pressed short."),
332                                            "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR);
333 
334                                 b->manager->hibernate_key_long_press_event_source = sd_event_source_unref(b->manager->hibernate_key_long_press_event_source);
335 
336                                 manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
337                         }
338                         break;
339                 }
340 
341         } else if (ev.type == EV_SW && ev.value > 0) {
342 
343                 if (ev.code == SW_LID) {
344                         log_struct(LOG_INFO,
345                                    LOG_MESSAGE("Lid closed."),
346                                    "MESSAGE_ID=" SD_MESSAGE_LID_CLOSED_STR);
347 
348                         b->lid_closed = true;
349                         button_lid_switch_handle_action(b->manager, true);
350                         button_install_check_event_source(b);
351 
352                 } else if (ev.code == SW_DOCK) {
353                         log_struct(LOG_INFO,
354                                    LOG_MESSAGE("System docked."),
355                                    "MESSAGE_ID=" SD_MESSAGE_SYSTEM_DOCKED_STR);
356 
357                         b->docked = true;
358                 }
359 
360         } else if (ev.type == EV_SW && ev.value == 0) {
361 
362                 if (ev.code == SW_LID) {
363                         log_struct(LOG_INFO,
364                                    LOG_MESSAGE("Lid opened."),
365                                    "MESSAGE_ID=" SD_MESSAGE_LID_OPENED_STR);
366 
367                         b->lid_closed = false;
368                         b->check_event_source = sd_event_source_unref(b->check_event_source);
369 
370                 } else if (ev.code == SW_DOCK) {
371                         log_struct(LOG_INFO,
372                                    LOG_MESSAGE("System undocked."),
373                                    "MESSAGE_ID=" SD_MESSAGE_SYSTEM_UNDOCKED_STR);
374 
375                         b->docked = false;
376                 }
377         }
378 
379         return 0;
380 }
381 
button_suitable(int fd)382 static int button_suitable(int fd) {
383         unsigned long types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1];
384 
385         assert(fd >= 0);
386 
387         if (ioctl(fd, EVIOCGBIT(EV_SYN, sizeof types), types) < 0)
388                 return -errno;
389 
390         if (bitset_get(types, EV_KEY)) {
391                 unsigned long keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1];
392 
393                 if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof keys), keys) < 0)
394                         return -errno;
395 
396                 if (bitset_get(keys, KEY_POWER) ||
397                     bitset_get(keys, KEY_POWER2) ||
398                     bitset_get(keys, KEY_SLEEP) ||
399                     bitset_get(keys, KEY_SUSPEND) ||
400                     bitset_get(keys, KEY_RESTART))
401                         return true;
402         }
403 
404         if (bitset_get(types, EV_SW)) {
405                 unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1];
406 
407                 if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof switches), switches) < 0)
408                         return -errno;
409 
410                 if (bitset_get(switches, SW_LID) ||
411                     bitset_get(switches, SW_DOCK))
412                         return true;
413         }
414 
415         return false;
416 }
417 
button_set_mask(const char * name,int fd)418 static int button_set_mask(const char *name, int fd) {
419         unsigned long
420                 types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {},
421                 keys[CONST_MAX5(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND, KEY_RESTART)/ULONG_BITS+1] = {},
422                 switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
423         struct input_mask mask;
424 
425         assert(name);
426         assert(fd >= 0);
427 
428         bitset_put(types, EV_KEY);
429         bitset_put(types, EV_SW);
430 
431         mask = (struct input_mask) {
432                 .type = EV_SYN,
433                 .codes_size = sizeof(types),
434                 .codes_ptr = PTR_TO_UINT64(types),
435         };
436 
437         if (ioctl(fd, EVIOCSMASK, &mask) < 0)
438                 /* Log only at debug level if the kernel doesn't do EVIOCSMASK yet */
439                 return log_full_errno(IN_SET(errno, ENOTTY, EOPNOTSUPP, EINVAL) ? LOG_DEBUG : LOG_WARNING,
440                                       errno, "Failed to set EV_SYN event mask on /dev/input/%s: %m", name);
441 
442         bitset_put(keys, KEY_POWER);
443         bitset_put(keys, KEY_POWER2);
444         bitset_put(keys, KEY_SLEEP);
445         bitset_put(keys, KEY_SUSPEND);
446         bitset_put(keys, KEY_RESTART);
447 
448         mask = (struct input_mask) {
449                 .type = EV_KEY,
450                 .codes_size = sizeof(keys),
451                 .codes_ptr = PTR_TO_UINT64(keys),
452         };
453 
454         if (ioctl(fd, EVIOCSMASK, &mask) < 0)
455                 return log_warning_errno(errno, "Failed to set EV_KEY event mask on /dev/input/%s: %m", name);
456 
457         bitset_put(switches, SW_LID);
458         bitset_put(switches, SW_DOCK);
459 
460         mask = (struct input_mask) {
461                 .type = EV_SW,
462                 .codes_size = sizeof(switches),
463                 .codes_ptr = PTR_TO_UINT64(switches),
464         };
465 
466         if (ioctl(fd, EVIOCSMASK, &mask) < 0)
467                 return log_warning_errno(errno, "Failed to set EV_SW event mask on /dev/input/%s: %m", name);
468 
469         return 0;
470 }
471 
button_open(Button * b)472 int button_open(Button *b) {
473         _cleanup_(asynchronous_closep) int fd = -1;
474         const char *p;
475         char name[256];
476         int r;
477 
478         assert(b);
479 
480         b->fd = asynchronous_close(b->fd);
481 
482         p = strjoina("/dev/input/", b->name);
483 
484         fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
485         if (fd < 0)
486                 return log_warning_errno(errno, "Failed to open %s: %m", p);
487 
488         r = button_suitable(fd);
489         if (r < 0)
490                 return log_warning_errno(r, "Failed to determine whether input device %s is relevant to us: %m", p);
491         if (r == 0)
492                 return log_debug_errno(SYNTHETIC_ERRNO(EADDRNOTAVAIL),
493                                        "Device %s does not expose keys or switches relevant to us, ignoring.", p);
494 
495         if (ioctl(fd, EVIOCGNAME(sizeof name), name) < 0)
496                 return log_error_errno(errno, "Failed to get input name for %s: %m", p);
497 
498         (void) button_set_mask(b->name, fd);
499 
500         b->io_event_source = sd_event_source_unref(b->io_event_source);
501         r = sd_event_add_io(b->manager->event, &b->io_event_source, fd, EPOLLIN, button_dispatch, b);
502         if (r < 0)
503                 return log_error_errno(r, "Failed to add button event for %s: %m", p);
504 
505         b->fd = TAKE_FD(fd);
506         log_info("Watching system buttons on %s (%s)", p, name);
507         return 0;
508 }
509 
button_check_switches(Button * b)510 int button_check_switches(Button *b) {
511         unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
512         assert(b);
513 
514         if (b->fd < 0)
515                 return -EINVAL;
516 
517         if (ioctl(b->fd, EVIOCGSW(sizeof(switches)), switches) < 0)
518                 return -errno;
519 
520         b->lid_closed = bitset_get(switches, SW_LID);
521         b->docked = bitset_get(switches, SW_DOCK);
522 
523         if (b->lid_closed)
524                 button_install_check_event_source(b);
525 
526         return 0;
527 }
528