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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user