[gnome-shell] loginManager: Make API promise-based



commit a3db9093834e500d10a5f35f45c499ed1f16854d
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Jun 23 15:45:44 2022 +0200

    loginManager: Make API promise-based
    
    The LoginManager abstraction is still mostly callback-based, not
    least because the methods are thin wrappers around logind D-Bus
    calls.
    
    However as gjs' dbus wrapper now generates promised-based wrappers
    as well, we can implement a proper async API just as naturally.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2344>

 js/gdm/loginDialog.js     |  11 +++--
 js/misc/loginManager.js   | 102 +++++++++++++++++++--------------------
 js/misc/systemActions.js  |  12 ++---
 js/ui/endSessionDialog.js | 119 ++++++++++++++++++++++++----------------------
 js/ui/screenShield.js     |  21 ++++----
 5 files changed, 133 insertions(+), 132 deletions(-)
---
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
index 573a4b1060..bd1a6591a1 100644
--- a/js/gdm/loginDialog.js
+++ b/js/gdm/loginDialog.js
@@ -529,7 +529,7 @@ var LoginDialog = GObject.registerClass({
         this._realmManager.connectObject('login-format-changed',
             this._showRealmLoginHint.bind(this), this);
 
-        LoginManager.getLoginManager().getCurrentSessionProxy(this._gotGreeterSessionProxy.bind(this));
+        this._getGreeterSessionProxy();
 
         // If the user list is enabled, it should take key focus; make sure the
         // screen shield is initialized first to prevent it from stealing the
@@ -982,10 +982,11 @@ var LoginDialog = GObject.registerClass({
         });
     }
 
-    _gotGreeterSessionProxy(proxy) {
-        this._greeterSessionProxy = proxy;
-        proxy.connectObject('g-properties-changed', () => {
-            if (proxy.Active)
+    async _getGreeterSessionProxy() {
+        const loginManager = LoginManager.getLoginManager();
+        this._greeterSessionProxy = await loginManager.getCurrentSessionProxy();
+        this._greeterSessionProxy?.connectObject('g-properties-changed', () => {
+            if (this._greeterSessionProxy.Active)
                 this._loginScreenSessionActivated();
         }, this);
     }
diff --git a/js/misc/loginManager.js b/js/misc/loginManager.js
index f5ebaf6575..6317b1dc4a 100644
--- a/js/misc/loginManager.js
+++ b/js/misc/loginManager.js
@@ -101,11 +101,9 @@ var LoginManagerSystemd = class extends Signals.EventEmitter {
                                   this._prepareForSleep.bind(this));
     }
 
-    getCurrentSessionProxy(callback) {
-        if (this._currentSession) {
-            callback(this._currentSession);
-            return;
-        }
+    async getCurrentSessionProxy() {
+        if (this._currentSession)
+            return this._currentSession;
 
         let sessionId = GLib.getenv('XDG_SESSION_ID');
         if (!sessionId) {
@@ -131,63 +129,60 @@ var LoginManagerSystemd = class extends Signals.EventEmitter {
 
                 if (!sessionId) {
                     log('No, failed to get session from logind.');
-                    return;
+                    return null;
                 }
             }
         }
 
-        this._proxy.GetSessionRemote(sessionId, (result, error) => {
-            if (error) {
-                logError(error, 'Could not get a proxy for the current session');
-            } else {
-                this._currentSession = new SystemdLoginSession(Gio.DBus.system,
-                                                               'org.freedesktop.login1',
-                                                               result[0]);
-                callback(this._currentSession);
-            }
-        });
+        try {
+            const [objectPath] = await this._proxy.GetSessionAsync(sessionId);
+            this._currentSession = new SystemdLoginSession(Gio.DBus.system,
+                'org.freedesktop.login1', objectPath);
+            return this._currentSession;
+        } catch (error) {
+            logError(error, 'Could not get a proxy for the current session');
+            return null;
+        }
     }
 
-    canSuspend(asyncCallback) {
-        this._proxy.CanSuspendRemote((result, error) => {
-            if (error) {
-                asyncCallback(false, false);
-            } else {
-                let needsAuth = result[0] == 'challenge';
-                let canSuspend = needsAuth || result[0] == 'yes';
-                asyncCallback(canSuspend, needsAuth);
-            }
-        });
+    async canSuspend() {
+        try {
+            const [result] = await this._proxy.CanSuspendAsync();
+            const needsAuth = result === 'challenge';
+            const canSuspend = needsAuth || result === 'yes';
+            return [canSuspend, needsAuth];
+        } catch (error) {
+            return [false, false];
+        }
     }
 
-    canRebootToBootLoaderMenu(asyncCallback) {
-        this._proxy.CanRebootToBootLoaderMenuRemote((result, error) => {
-            if (error) {
-                asyncCallback(false, false);
-            } else {
-                const needsAuth = result[0] === 'challenge';
-                const canRebootToBootLoaderMenu = needsAuth || result[0] === 'yes';
-                asyncCallback(canRebootToBootLoaderMenu, needsAuth);
-            }
-        });
+    async canRebootToBootLoaderMenu() {
+        try {
+            const [result] = await this._proxy.CanRebootToBootLoaderMenuAsync();
+            const needsAuth = result[0] === 'challenge';
+            const canRebootToBootLoaderMenu = needsAuth || result[0] === 'yes';
+            return [canRebootToBootLoaderMenu, needsAuth];
+        } catch (error) {
+            return [false, false];
+        }
     }
 
     setRebootToBootLoaderMenu() {
         /* Parameter is timeout in usec, show to menu for 60 seconds */
-        this._proxy.SetRebootToBootLoaderMenuRemote(60000000);
+        this._proxy.SetRebootToBootLoaderMenuAsync(60000000);
     }
 
-    listSessions(asyncCallback) {
-        this._proxy.ListSessionsRemote((result, error) => {
-            if (error)
-                asyncCallback([]);
-            else
-                asyncCallback(result[0]);
-        });
+    async listSessions() {
+        try {
+            const [sessions] = await this._proxy.ListSessionsAsync();
+            return sessions;
+        } catch (e) {
+            return [];
+        }
     }
 
     suspend() {
-        this._proxy.SuspendRemote(true);
+        this._proxy.SuspendAsync(true);
     }
 
     async inhibit(reason, cancellable) {
@@ -206,25 +201,26 @@ var LoginManagerSystemd = class extends Signals.EventEmitter {
 };
 
 var LoginManagerDummy = class extends Signals.EventEmitter  {
-    getCurrentSessionProxy(_callback) {
+    getCurrentSessionProxy() {
         // we could return a DummySession object that fakes whatever callers
         // expect (at the time of writing: connect() and connectSignal()
-        // methods), but just never calling the callback should be safer
+        // methods), but just never settling the promise should be safer
+        return new Promise(() => {});
     }
 
-    canSuspend(asyncCallback) {
-        asyncCallback(false, false);
+    canSuspend() {
+        return new Promise(resolve => resolve([false, false]));
     }
 
-    canRebootToBootLoaderMenu(asyncCallback) {
-        asyncCallback(false, false);
+    canRebootToBootLoaderMenu() {
+        return new Promise(resolve => resolve([false, false]));
     }
 
     setRebootToBootLoaderMenu() {
     }
 
-    listSessions(asyncCallback) {
-        asyncCallback([]);
+    listSessions() {
+        return new Promise(resolve => resolve([]));
     }
 
     suspend() {
diff --git a/js/misc/systemActions.js b/js/misc/systemActions.js
index 6d0e0497cf..42bce0198a 100644
--- a/js/misc/systemActions.js
+++ b/js/misc/systemActions.js
@@ -347,13 +347,11 @@ const SystemActions = GObject.registerClass({
         this.notify('can-restart');
     }
 
-    _updateHaveSuspend() {
-        this._loginManager.canSuspend(
-            (canSuspend, needsAuth) => {
-                this._canHaveSuspend = canSuspend;
-                this._suspendNeedsAuth = needsAuth;
-                this._updateSuspend();
-            });
+    async _updateHaveSuspend() {
+        const [canSuspend, needsAuth] = await this._loginManager.canSuspend();
+        this._canHaveSuspend = canSuspend;
+        this._suspendNeedsAuth = needsAuth;
+        this._updateSuspend();
     }
 
     _updateSuspend() {
diff --git a/js/ui/endSessionDialog.js b/js/ui/endSessionDialog.js
index dddfd51f06..1f0b6afc25 100644
--- a/js/ui/endSessionDialog.js
+++ b/js/ui/endSessionDialog.js
@@ -234,10 +234,8 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
         });
 
         this._loginManager = LoginManager.getLoginManager();
-        this._loginManager.canRebootToBootLoaderMenu(
-            (canRebootToBootLoaderMenu, unusedNeedsAuth) => {
-                this._canRebootToBootLoaderMenu = canRebootToBootLoaderMenu;
-            });
+        this._canRebootToBootLoaderMenu = false;
+        this._getCanRebootToBootLoaderMenu();
 
         this._userManager = AccountsService.UserManager.get_default();
         this._user = this._userManager.get_user(GLib.get_user_name());
@@ -306,6 +304,11 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
         this._dbusImpl.export(Gio.DBus.session, '/org/gnome/SessionManager/EndSessionDialog');
     }
 
+    async _getCanRebootToBootLoaderMenu() {
+        const [canRebootToBootLoaderMenu] = await this._loginManager.canRebootToBootLoaderMenu();
+        this._canRebootToBootLoaderMenu = canRebootToBootLoaderMenu;
+    }
+
     async _onPkOfflineProxyCreated(proxy, error) {
         if (error) {
             log(error.message);
@@ -645,65 +648,65 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
         this._sync();
     }
 
-    _loadSessions() {
-        this._loginManager.listSessions(result => {
-            for (let i = 0; i < result.length; i++) {
-                let [id_, uid_, userName, seat_, sessionPath] = result[i];
-                let proxy = new LogindSession(Gio.DBus.system, 'org.freedesktop.login1', sessionPath);
+    async _loadSessions() {
+        let sessionId = GLib.getenv('XDG_SESSION_ID');
+        if (!sessionId) {
+            const currentSessionProxy = await this._loginManager.getCurrentSessionProxy();
+            sessionId = currentSessionProxy.Id;
+            log(`endSessionDialog: No XDG_SESSION_ID, fetched from logind: ${sessionId}`);
+        }
 
-                if (proxy.Class != 'user')
-                    continue;
+        const sessions = await this._loginManager.listSessions();
+        for (const [id_, uid_, userName, seat_, sessionPath] of sessions) {
+            let proxy = new LogindSession(Gio.DBus.system, 'org.freedesktop.login1', sessionPath);
 
-                if (proxy.State == 'closing')
-                    continue;
+            if (proxy.Class !== 'user')
+                continue;
 
-                let sessionId = GLib.getenv('XDG_SESSION_ID');
-                if (!sessionId) {
-                    this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
-                        sessionId = currentSessionProxy.Id;
-                        log(`endSessionDialog: No XDG_SESSION_ID, fetched from logind: ${sessionId}`);
-                    });
-                }
-
-                if (proxy.Id == sessionId)
-                    continue;
-
-                const session = {
-                    user: this._userManager.get_user(userName),
-                    username: userName,
-                    type: proxy.Type,
-                    remote: proxy.Remote,
-                };
-                const nSessions = this._sessions.push(session);
-
-                let userAvatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
-                userAvatar.update();
-
-                userName = session.user.get_real_name() ?? session.username;
-
-                let userLabelText;
-                if (session.remote)
-                    /* Translators: Remote here refers to a remote session, like a ssh login */
-                    userLabelText = _('%s (remote)').format(userName);
-                else if (session.type === 'tty')
-                    /* Translators: Console here refers to a tty like a VT console */
-                    userLabelText = _('%s (console)').format(userName);
-                else
-                    userLabelText = userName;
-
-                let listItem = new Dialog.ListSectionItem({
-                    icon_actor: userAvatar,
-                    title: userLabelText,
-                });
-                this._sessionSection.list.add_child(listItem);
+            if (proxy.State === 'closing')
+                continue;
 
-                // limit the number of entries
-                if (nSessions === MAX_USERS_IN_SESSION_DIALOG)
-                    break;
-            }
+            if (proxy.Id === sessionId)
+                continue;
 
-            this._sync();
-        });
+            const session = {
+                user: this._userManager.get_user(userName),
+                username: userName,
+                type: proxy.Type,
+                remote: proxy.Remote,
+            };
+            const nSessions = this._sessions.push(session);
+
+            let userAvatar = new UserWidget.Avatar(session.user, {
+                iconSize: _ITEM_ICON_SIZE,
+            });
+            userAvatar.update();
+
+            const displayUserName =
+                session.user.get_real_name() ?? session.username;
+
+            let userLabelText;
+            if (session.remote)
+                /* Translators: Remote here refers to a remote session, like a ssh login */
+                userLabelText = _('%s (remote)').format(displayUserName);
+            else if (session.type === 'tty')
+                /* Translators: Console here refers to a tty like a VT console */
+                userLabelText = _('%s (console)').format(displayUserName);
+            else
+                userLabelText = userName;
+
+            let listItem = new Dialog.ListSectionItem({
+                icon_actor: userAvatar,
+                title: userLabelText,
+            });
+            this._sessionSection.list.add_child(listItem);
+
+            // limit the number of entries
+            if (nSessions === MAX_USERS_IN_SESSION_DIALOG)
+                break;
+        }
+
+        this._sync();
     }
 
     async _getUpdateInfo() {
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index d19f7503d1..7148c1e623 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -106,15 +106,7 @@ var ScreenShield = class extends Signals.EventEmitter {
                                    this._prepareForSleep.bind(this));
 
         this._loginSession = null;
-        this._loginManager.getCurrentSessionProxy(sessionProxy => {
-            this._loginSession = sessionProxy;
-            this._loginSession.connectSignal('Lock',
-                                             () => this.lock(false));
-            this._loginSession.connectSignal('Unlock',
-                                             () => this.deactivate(false));
-            this._loginSession.connect('g-properties-changed', this._syncInhibitor.bind(this));
-            this._syncInhibitor();
-        });
+        this._getLoginSession();
 
         this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA });
         this._settings.connect(`changed::${LOCK_ENABLED_KEY}`, this._syncInhibitor.bind(this));
@@ -152,6 +144,17 @@ var ScreenShield = class extends Signals.EventEmitter {
         this._syncInhibitor();
     }
 
+    async _getLoginSession() {
+        this._loginSession = await this._loginManager.getCurrentSessionProxy();
+        this._loginSession.connectSignal('Lock',
+            () => this.lock(false));
+        this._loginSession.connectSignal('Unlock',
+            () => this.deactivate(false));
+        this._loginSession.connect('g-properties-changed',
+            () => this._syncInhibitor());
+        this._syncInhibitor();
+    }
+
     _setActive(active) {
         let prevIsActive = this._isActive;
         this._isActive = active;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]