[gnome-software/gnome-3-14] Hide updates UI on managed systems



commit 032c5449fbafbecbfce472b1b3047e14c48876d8
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 21 18:01:15 2015 -0400

    Hide updates UI on managed systems
    
    It doesn't make sense to show the updates UI to a user
    who does not have the trigger-offline-updates privilege,
    so hide the Updates tab button in this case, and don't
    notify the user about available updates.
    
    If the user manages to open the updates tab anyway (e.g.
    by using the --mode=updates commandline option), tell him
    that updates are managed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=749744

 configure.ac             |    2 ++
 src/Makefile.am          |    2 ++
 src/gs-application.c     |   27 ++++++++++++++++++++++++++-
 src/gs-offline-updates.c |   27 +++++++++++++++++++++++++++
 src/gs-offline-updates.h |    3 +++
 src/gs-shell-updates.c   |   42 +++++++++++++++++++++++++++++++++++++++++-
 src/gs-shell-updates.ui  |   37 +++++++++++++++++++++++++++++++++++++
 src/gs-shell.c           |   28 ++++++++++++++++++++++++++++
 8 files changed, 166 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 2af57e2..0364050 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,8 @@ PKG_CHECK_MODULES(SQLITE, sqlite3)
 PKG_CHECK_MODULES(SOUP, libsoup-2.4)
 PKG_CHECK_MODULES(GSETTINGS_DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.11.5)
 PKG_CHECK_MODULES(GNOME_DESKTOP, gnome-desktop-3.0)
+PKG_CHECK_MODULES(POLKIT, polkit-gobject-1)
+AC_PATH_PROG(APPSTREAM_UTIL, [appstream-util], [unfound])
 AC_ARG_ENABLE(man,
               [AS_HELP_STRING([--enable-man],
                               [generate man pages [default=auto]])],,
diff --git a/src/Makefile.am b/src/Makefile.am
index 708ade1..aaf2350 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ AM_CPPFLAGS =                                           \
        $(SOUP_CFLAGS)                                  \
        $(PACKAGEKIT_CFLAGS)                            \
        $(GNOME_DESKTOP_CFLAGS)                         \
+       $(POLKIT_CFLAGS)                                \
        -DG_LOG_DOMAIN=\"Gs\"                           \
        -DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE  \
        -DGS_MODULESETDIR=\"$(datadir)/gnome-software/modulesets.d\" \
@@ -175,6 +176,7 @@ gnome_software_LDADD =                                      \
        $(SOUP_LIBS)                                    \
        $(PACKAGEKIT_LIBS)                              \
        $(GNOME_DESKTOP_LIBS)                           \
+       $(POLKIT_LIBS)                                  \
        -lm
 
 gnome_software_CFLAGS =                                        \
diff --git a/src/gs-application.c b/src/gs-application.c
index 4e069ea..898fb7a 100644
--- a/src/gs-application.c
+++ b/src/gs-application.c
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
+#include <gio/gio.h>
 #include <gio/gdesktopappinfo.h>
 #include <packagekit-glib2/packagekit.h>
 
@@ -41,6 +42,7 @@
 #include "gs-shell-search-provider.h"
 #include "gs-offline-updates.h"
 #include "gs-folders.h"
+#include "gs-utils.h"
 
 
 struct _GsApplication {
@@ -91,7 +93,8 @@ download_updates_setting_changed (GSettings     *settings,
                                   const gchar   *key,
                                   GsApplication *app)
 {
-       if (g_settings_get_boolean (settings, key)) {
+       if (!gs_updates_are_managed () &&
+           g_settings_get_boolean (settings, key)) {
                g_debug ("Enabling update monitor");
                app->update_monitor = gs_update_monitor_new (app);
        } else {
@@ -101,6 +104,27 @@ download_updates_setting_changed (GSettings     *settings,
 }
 
 static void
+on_permission_changed (GPermission *permission,
+                       GParamSpec  *pspec,
+                       gpointer     data)
+{
+       GsApplication *app = data;
+
+       if (app->settings)
+               download_updates_setting_changed (app->settings, "download-updates", app);
+}
+
+static void
+gs_application_monitor_permission (GsApplication *app)
+{
+       GPermission *permission;
+
+       permission = gs_offline_updates_permission_get ();
+       g_signal_connect (permission, "notify",
+                         G_CALLBACK (on_permission_changed), app);
+}
+
+static void
 gs_application_monitor_updates (GsApplication *app)
 {
        g_signal_connect (app->settings, "changed::download-updates",
@@ -478,6 +502,7 @@ gs_application_startup (GApplication *application)
        GS_APPLICATION (application)->proxy_settings = gs_proxy_settings_new ();
        GS_APPLICATION (application)->dbus_helper = gs_dbus_helper_new ();
        GS_APPLICATION (application)->settings = g_settings_new ("org.gnome.software");
+       gs_application_monitor_permission (GS_APPLICATION (application));
        gs_application_monitor_updates (GS_APPLICATION (application));
        gs_application_provide_search (GS_APPLICATION (application));
        gs_application_monitor_network (GS_APPLICATION (application));
diff --git a/src/gs-offline-updates.c b/src/gs-offline-updates.c
index 2187086..28fde90 100644
--- a/src/gs-offline-updates.c
+++ b/src/gs-offline-updates.c
@@ -23,6 +23,7 @@
 
 #include <glib/gi18n.h>
 #include <packagekit-glib2/packagekit.h>
+#include <polkit/polkit.h>
 
 #include "gs-offline-updates.h"
 #include "gs-utils.h"
@@ -172,4 +173,30 @@ out:
                g_object_unref (results);
 }
 
+GPermission *
+gs_offline_updates_permission_get (void)
+{
+       static GPermission *permission;
+
+       if (!permission)
+               permission = polkit_permission_new_sync ("org.freedesktop.packagekit.trigger-offline-update",
+                                                         NULL, NULL, NULL);
+
+       return permission;
+}
+
+gboolean
+gs_updates_are_managed (void)
+{
+       GPermission *permission;
+       gboolean managed;
+
+       permission = gs_offline_updates_permission_get ();
+       managed = !g_permission_get_allowed (permission) &&
+                  !g_permission_get_can_acquire (permission);
+
+       return managed;
+}
+
+
 /* vim: set noexpandtab: */
diff --git a/src/gs-offline-updates.h b/src/gs-offline-updates.h
index be75c2e..39d38f3 100644
--- a/src/gs-offline-updates.h
+++ b/src/gs-offline-updates.h
@@ -28,6 +28,9 @@ G_BEGIN_DECLS
 
 void     gs_offline_updates_show_error         (void);
 
+GPermission    *gs_offline_updates_permission_get      (void);
+gboolean         gs_updates_are_managed                (void);
+
 
 G_END_DECLS
 
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index a5baf2a..aadc5f9 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -33,6 +33,7 @@
 #include "gs-markdown.h"
 #include "gs-update-dialog.h"
 #include "gs-update-list.h"
+#include "gs-application.h"
 
 #include <gdesktop-enums.h>
 #include <langinfo.h>
@@ -45,6 +46,7 @@ typedef enum {
        GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES,
        GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES,
        GS_SHELL_UPDATES_STATE_NO_UPDATES,
+       GS_SHELL_UPDATES_STATE_MANAGED,
        GS_SHELL_UPDATES_STATE_HAS_UPDATES,
        GS_SHELL_UPDATES_STATE_FAILED,
        GS_SHELL_UPDATES_STATE_LAST,
@@ -236,6 +238,7 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
                break;
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
+       case GS_SHELL_UPDATES_STATE_MANAGED:
        case GS_SHELL_UPDATES_STATE_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_FAILED:
                gs_stop_spinner (GTK_SPINNER (priv->spinner_updates));
@@ -268,6 +271,7 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
                break;
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
+       case GS_SHELL_UPDATES_STATE_MANAGED:
        case GS_SHELL_UPDATES_STATE_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_FAILED:
                break;
@@ -286,6 +290,7 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_NO_UPDATES:
        case GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES:
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
+       case GS_SHELL_UPDATES_STATE_MANAGED:
        case GS_SHELL_UPDATES_STATE_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_STARTUP:
        case GS_SHELL_UPDATES_STATE_FAILED:
@@ -309,6 +314,7 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
                break;
        case GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES:
        case GS_SHELL_UPDATES_STATE_STARTUP:
+       case GS_SHELL_UPDATES_STATE_MANAGED:
                widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_refresh"));
                gtk_widget_hide (widget);
                break;
@@ -342,6 +348,7 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_NO_UPDATES:
        case GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES:
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
+       case GS_SHELL_UPDATES_STATE_MANAGED:
        case GS_SHELL_UPDATES_STATE_FAILED:
                gtk_widget_hide (widget);
                break;
@@ -383,6 +390,9 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES:
                gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "view");
                break;
+       case GS_SHELL_UPDATES_STATE_MANAGED:
+               gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "managed");
+               break;
        case GS_SHELL_UPDATES_STATE_FAILED:
                gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "failed");
                break;
@@ -416,6 +426,8 @@ gs_shell_updates_set_state (GsShellUpdates *shell_updates,
                            GsShellUpdatesState state)
 {
        shell_updates->priv->state = state;
+       if (gs_updates_are_managed ())
+               shell_updates->priv->state = GS_SHELL_UPDATES_STATE_MANAGED;
        gs_shell_updates_update_ui_state (shell_updates);
 }
 
@@ -454,7 +466,7 @@ gs_shell_updates_get_updates_cb (GsPluginLoader *plugin_loader,
        }
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_updates_counter"));
-       if (list != NULL) {
+       if (list != NULL && !gs_updates_are_managed ()) {
                gchar *text;
                text = g_strdup_printf ("%d", g_list_length (list));
                gtk_label_set_label (GTK_LABEL (widget), text);
@@ -901,6 +913,32 @@ gs_shell_updates_status_changed_cb (GsPluginLoader *plugin_loader,
        gs_shell_updates_update_ui_state (shell_updates);
 }
 
+static void
+on_permission_changed (GPermission *permission,
+                       GParamSpec  *pspec,
+                       gpointer     data)
+{
+        GsShellUpdates *shell_updates = data;
+        GsShellUpdatesPrivate *priv = shell_updates->priv;
+
+       if (gs_updates_are_managed()) {
+               gs_shell_updates_set_state (shell_updates, GS_SHELL_UPDATES_STATE_MANAGED);
+       }
+       else if (priv->state == GS_SHELL_UPDATES_STATE_MANAGED) {
+               gs_shell_updates_set_state (shell_updates, GS_SHELL_UPDATES_STATE_NO_UPDATES);
+       }
+}
+
+static void
+gs_shell_updates_monitor_permission (GsShellUpdates *shell_updates)
+{
+        GPermission *permission;
+
+        permission = gs_offline_updates_permission_get ();
+        g_signal_connect (permission, "notify",
+                          G_CALLBACK (on_permission_changed), shell_updates);
+}
+
 void
 gs_shell_updates_setup (GsShellUpdates *shell_updates,
                        GsShell *shell,
@@ -944,6 +982,8 @@ gs_shell_updates_setup (GsShellUpdates *shell_updates,
                          G_CALLBACK (gs_shell_updates_button_network_settings_cb),
                          shell_updates);
 
+       gs_shell_updates_monitor_permission (shell_updates);
+
        g_signal_connect (priv->control, "notify::network-state",
                          G_CALLBACK (gs_shell_updates_notify_network_state_cb),
                          shell_updates);
diff --git a/src/gs-shell-updates.ui b/src/gs-shell-updates.ui
index 3fefe8d..e2ac75f 100644
--- a/src/gs-shell-updates.ui
+++ b/src/gs-shell-updates.ui
@@ -280,6 +280,43 @@
             <property name="name">failed</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">128</property>
+                <property name="icon_name">action-unavailable-symbolic</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="wrap">True</property>
+                <property name="max-width-chars">60</property>
+                <property name="label" translatable="No">Updates are automatically managed</property>
+                <attributes>
+                  <attribute name="scale" value="1.4"/>
+                </attributes>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="name">managed</property>
+          </packing>
+        </child>
       </object>
     </child>
   </template>
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 5118e2a..3735c93 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -35,6 +35,7 @@
 #include "gs-shell-category.h"
 #include "gs-sources-dialog.h"
 #include "gs-update-dialog.h"
+#include "gs-offline-updates.h"
 
 static const gchar *page_name[] = {
        "overview",
@@ -170,6 +171,8 @@ gs_shell_change_mode (GsShell *shell,
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_updates"));
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), mode == GS_SHELL_MODE_UPDATES);
+       gtk_widget_set_visible (widget, !gs_updates_are_managed() || mode == GS_SHELL_MODE_UPDATES);
+
        priv->ignore_primary_buttons = FALSE;
 
        /* switch page */
@@ -514,6 +517,29 @@ gs_shell_main_window_mapped_cb (GtkWidget *widget, GsShell *shell)
                                    gtk_widget_get_scale_factor (widget));
 }
 
+static void
+on_permission_changed (GPermission *permission,
+                       GParamSpec  *pspec,
+                       gpointer     data)
+{
+        GsShell *shell = data;
+       GsShellPrivate *priv = shell->priv;
+       GtkWidget *widget;
+
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_updates"));
+       gtk_widget_set_visible (widget, !gs_updates_are_managed() || priv->mode == GS_SHELL_MODE_UPDATES);
+}
+
+static void
+gs_shell_monitor_permission (GsShell *shell)
+{
+        GPermission *permission;
+
+        permission = gs_offline_updates_permission_get ();
+        g_signal_connect (permission, "notify",
+                          G_CALLBACK (on_permission_changed), shell);
+}
+
 /**
  * gs_shell_setup:
  */
@@ -530,6 +556,8 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
                          G_CALLBACK (gs_shell_updates_changed_cb), shell);
        priv->cancellable = g_object_ref (cancellable);
 
+       gs_shell_monitor_permission (shell);
+
        /* get UI */
        priv->builder = gtk_builder_new_from_resource ("/org/gnome/Software/gnome-software.ui");
        priv->main_window = GTK_WINDOW (gtk_builder_get_object (priv->builder, "window_software"));


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