logind: rework logic to decide whether lock + idle + display applies to a session

Let's streamline the logic that decides whether the screen lock, idle
timeout or display election mechanism applies to a session class. Let's
add explicitly SESSION_CLASS_IS_XYZ() macros for each, and then resue
them at all suitable places, and refuse any attempts to use the
functionality on the wrong clases with a friendly error message.
This commit is contained in:
Lennart Poettering
2024-01-11 17:23:47 +01:00
parent b5100c736f
commit b4f01bc1df
5 changed files with 43 additions and 9 deletions
+3
View File
@@ -413,6 +413,9 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
dual_timestamp k;
int ih;
if (!SESSION_CLASS_CAN_IDLE(s->class))
continue;
ih = session_get_idle_hint(s, &k);
if (ih < 0)
return ih;
+15 -3
View File
@@ -216,7 +216,9 @@ int bus_session_method_lock(sd_bus_message *message, void *userdata, sd_bus_erro
if (r == 0)
return 1; /* Will call us back */
r = session_send_lock(s, strstr(sd_bus_message_get_member(message), "Lock"));
r = session_send_lock(s, /* lock= */ strstr(sd_bus_message_get_member(message), "Lock"));
if (r == -ENOTTY)
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Session does not support lock screen.");
if (r < 0)
return r;
@@ -248,7 +250,7 @@ static int method_set_idle_hint(sd_bus_message *message, void *userdata, sd_bus_
r = session_set_idle_hint(s, b);
if (r == -ENOTTY)
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Idle hint control is not supported on non-graphical sessions.");
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Idle hint control is not supported on non-graphical and non-user sessions.");
if (r < 0)
return r;
@@ -278,7 +280,11 @@ static int method_set_locked_hint(sd_bus_message *message, void *userdata, sd_bu
if (uid != 0 && uid != s->user->user_record->uid)
return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may set locked hint");
session_set_locked_hint(s, b);
r = session_set_locked_hint(s, b);
if (r == -ENOTTY)
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Session does not support lock screen.");
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
@@ -765,6 +771,9 @@ int session_send_lock(Session *s, bool lock) {
assert(s);
if (!SESSION_CLASS_CAN_LOCK(s->class))
return -ENOTTY;
p = session_bus_path(s);
if (!p)
return -ENOMEM;
@@ -786,6 +795,9 @@ int session_send_lock_all(Manager *m, bool lock) {
HASHMAP_FOREACH(session, m->sessions) {
int k;
if (!SESSION_CLASS_CAN_LOCK(session->class))
continue;
k = session_send_lock(session, lock);
if (k < 0)
r = k;
+11 -4
View File
@@ -1155,7 +1155,9 @@ found_atime:
int session_set_idle_hint(Session *s, bool b) {
assert(s);
if (!SESSION_TYPE_IS_GRAPHICAL(s->type))
if (!SESSION_CLASS_CAN_IDLE(s->class)) /* Only some session classes know the idle concept at all */
return -ENOTTY;
if (!SESSION_TYPE_IS_GRAPHICAL(s->type)) /* And only graphical session types can set the field explicitly */
return -ENOTTY;
if (s->idle_hint == b)
@@ -1181,15 +1183,20 @@ int session_get_locked_hint(Session *s) {
return s->locked_hint;
}
void session_set_locked_hint(Session *s, bool b) {
int session_set_locked_hint(Session *s, bool b) {
assert(s);
if (!SESSION_CLASS_CAN_LOCK(s->class))
return -ENOTTY;
if (s->locked_hint == b)
return;
return 0;
s->locked_hint = b;
(void) session_save(s);
(void) session_send_changed(s, "LockedHint", NULL);
session_send_changed(s, "LockedHint", NULL);
return 1;
}
void session_set_type(Session *s, SessionType t) {
+10 -1
View File
@@ -45,6 +45,15 @@ typedef enum SessionClass {
/* Which session classes can pin our user tracking? */
#define SESSION_CLASS_PIN_USER(class) (!IN_SET((class), SESSION_MANAGER, SESSION_MANAGER_EARLY))
/* Which session classes decide whether system is idle? (should only cover sessions that have input, and are not idle screens themselves)*/
#define SESSION_CLASS_CAN_IDLE(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER))
/* Which session classes have a lock screen concept? */
#define SESSION_CLASS_CAN_LOCK(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY))
/* Which sessions are candidates to become "display" sessions */
#define SESSION_CLASS_CAN_DISPLAY(class) (IN_SET((class), SESSION_USER, SESSION_USER_EARLY, SESSION_GREETER))
typedef enum SessionType {
SESSION_UNSPECIFIED,
SESSION_TTY,
@@ -158,7 +167,7 @@ bool session_is_active(Session *s);
int session_get_idle_hint(Session *s, dual_timestamp *t);
int session_set_idle_hint(Session *s, bool b);
int session_get_locked_hint(Session *s);
void session_set_locked_hint(Session *s, bool b);
int session_set_locked_hint(Session *s, bool b);
void session_set_type(Session *s, SessionType t);
int session_set_display(Session *s, const char *display);
int session_set_tty(Session *s, const char *tty);
+4 -1
View File
@@ -591,6 +591,9 @@ int user_get_idle_hint(User *u, dual_timestamp *t) {
dual_timestamp k;
int ih;
if (!SESSION_CLASS_CAN_IDLE(s->class))
continue;
ih = session_get_idle_hint(s, &k);
if (ih < 0)
return ih;
@@ -783,7 +786,7 @@ static bool elect_display_filter(Session *s) {
/* Return true if the session is a candidate for the user’s ‘primary session’ or ‘display’. */
assert(s);
return IN_SET(s->class, SESSION_USER, SESSION_GREETER) && s->started && !s->stopping;
return SESSION_CLASS_CAN_DISPLAY(s->class) && s->started && !s->stopping;
}
static int elect_display_compare(Session *s1, Session *s2) {