[gnome-shell/mcatanzaro/#2276] WIP: Fix prompt for updates on end session dialog



commit 0c4ab78bd932d6ff01af6204592717110f3046a6
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Tue Mar 17 20:56:33 2020 -0500

    WIP: Fix prompt for updates on end session dialog
    
    Since PackageKit 1.11.1, the prompt to install updates on the end
    session dialog has been (mostly) broken. The problem is that it only
    works if PackageKit is running at the time the end session dialog is
    opened; otherwise, our GDBusProxy has invalidated all of its properties,
    which we read to see if update is possible. We need to autostart
    PackageKit before reading its properties to fix this problem. That would
    be easy if we were calling a method to see if an update or distro
    upgrade were available, but since we're just checking a property,
    there's not really an obvious non-hackish way to do it. So I came up
    with this yucky hack: we can ping PackageKit, which will autostart it,
    then wait for it to update its properties. (The properties are not
    updated before we receive the reply to its ping.)
    
    The timeout is created to ensure that we don't fail to show the dialog
    if PackageKit responds to the ping but fails to update its properties in
    a reasonable amount of time. It's yucky, but we should be robust to that
    possibility.
    
    Fixes #2276

 js/ui/endSessionDialog.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)
---
diff --git a/js/ui/endSessionDialog.js b/js/ui/endSessionDialog.js
index 42ae0d3f26..8f4b183826 100644
--- a/js/ui/endSessionDialog.js
+++ b/js/ui/endSessionDialog.js
@@ -608,7 +608,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
         });
     }
 
-    OpenAsync(parameters, invocation) {
+    _continueOpenAsync(parameters, invocation) {
         let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
         this._totalSecondsToStayOpen = totalSecondsToStayOpen;
         this._type = type;
@@ -680,6 +680,57 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
         });
     }
 
+    OpenAsync(parameters, invocation) {
+        if (this._pkOfflineProxy && this._pkOfflineProxy.g_name_owner == null) {
+log('endSessionDialog: PackageKit name owner is null!');
+            // PackageKit exists but has quit. We need to launch it again before
+            // we can use its properties. A simple ping will do. We can't wait
+            // long, though, because we don't want to delay showing the dialog,
+            // so only give it 200ms (arbitrary).
+            let propertiesChangedID = 0;
+            let timeoutID = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
+                                             200,
+                                             () => {
+log('Timed out waiting for PackageKit daemon to refresh properties');
+                                                 GObject.signal_handler_disconnect(this._pkOfflineProxy, 
propertiesChangedID);
+                                                 this._continueOpenAsync(parameters, invocation);
+                                                 return false;
+                                             });
+            propertiesChangedID = this._pkOfflineProxy.connect(
+                'g-properties-changed',
+                (changed, invalidated) => {
+log('Yay we hit our success path! PackageKit refreshed properties!');
+                    // FIXME: check changed for the properties we use.
+                    GObject.signal_handler_disconnect(this._pkOfflineProxy, propertiesChangedID);
+                    GLib.Source.remove(timeoutID);
+                    this._continueOpenAsync(parameters, invocation);
+                });
+
+            // FIXME: Is it safe to pass null for the cancellable? Probably not?
+            // This would be a serious mistake if this were C.
+            let conn = this._pkOfflineProxy.get_connection();
+            conn.call('org.freedesktop.PackageKit',
+                      '/org/freedesktop/PackageKit',
+                      'org.freedesktop.DBus.Peer',
+                      'Ping',
+                      null, null,
+                      Gio.DBusCallFlags.NONE, 200, null,
+                      (source, res) => {
+                          try {
+                              conn.call_finish(res);
+                          } catch (e) {
+log('Failed to ping PackageKit daemon: %s'.format(e.toString()));
+                              GLib.Source.remove(timeoutID);
+                              GObject.signal_handler_disconnect(this._pkOfflineProxy, propertiesChangedID);
+                              this._continueOpenAsync(parameters, invocation);
+                          }
+                      });
+        } else {
+log('endSessionDialog: PackageKit is running RIGHT NOW!');
+            this._continueOpenAsync(parameters, invocation);
+        }
+    }
+
     Close(_parameters, _invocation) {
         this.close();
     }


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