Blame SOURCES/0001-info-Add-subscription-manager-integration.patch

06e1d8
From 3283b063af3f97cfc414766a42de80fc5ee43ba4 Mon Sep 17 00:00:00 2001
9b746a
From: Kalev Lember <klember@redhat.com>
9b746a
Date: Fri, 28 Jun 2019 17:14:36 +0200
06e1d8
Subject: [PATCH 1/4] info: Add subscription manager integration
9b746a
9b746a
---
9b746a
 panels/info/cc-info-overview-panel.c          | 157 ++++-
9b746a
 panels/info/cc-subscription-details-dialog.c  | 407 ++++++++++++
9b746a
 panels/info/cc-subscription-details-dialog.h  |  32 +
9b746a
 panels/info/cc-subscription-details-dialog.ui | 248 +++++++
9b746a
 panels/info/cc-subscription-register-dialog.c | 403 +++++++++++
9b746a
 panels/info/cc-subscription-register-dialog.h |  32 +
9b746a
 .../info/cc-subscription-register-dialog.ui   | 623 ++++++++++++++++++
9b746a
 panels/info/info-overview.ui                  | 138 +++-
9b746a
 panels/info/info.gresource.xml                |   2 +
9b746a
 panels/info/meson.build                       |   4 +
9b746a
 po/POTFILES.in                                |   4 +
9b746a
 11 files changed, 2038 insertions(+), 12 deletions(-)
9b746a
 create mode 100644 panels/info/cc-subscription-details-dialog.c
9b746a
 create mode 100644 panels/info/cc-subscription-details-dialog.h
9b746a
 create mode 100644 panels/info/cc-subscription-details-dialog.ui
9b746a
 create mode 100644 panels/info/cc-subscription-register-dialog.c
9b746a
 create mode 100644 panels/info/cc-subscription-register-dialog.h
9b746a
 create mode 100644 panels/info/cc-subscription-register-dialog.ui
9b746a
9b746a
diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c
9b746a
index 2256b730c..1467060f9 100644
9b746a
--- a/panels/info/cc-info-overview-panel.c
9b746a
+++ b/panels/info/cc-info-overview-panel.c
06e1d8
@@ -1,118 +1,126 @@
06e1d8
 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
06e1d8
  *
06e1d8
  * Copyright (C) 2017 Mohammed Sadiq <sadiq@sadiqpk.org>
06e1d8
  * Copyright (C) 2010 Red Hat, Inc
06e1d8
  * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
06e1d8
  *
06e1d8
  * This program is free software; you can redistribute it and/or modify
06e1d8
  * it under the terms of the GNU General Public License as published by
06e1d8
  * the Free Software Foundation; either version 2 of the License, or
06e1d8
  * (at your option) any later version.
06e1d8
  *
06e1d8
  * This program is distributed in the hope that it will be useful,
06e1d8
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
06e1d8
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
06e1d8
  * GNU General Public License for more details.
06e1d8
  *
06e1d8
  * You should have received a copy of the GNU General Public License
06e1d8
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
06e1d8
  *
06e1d8
  */
06e1d8
 
06e1d8
 #include <config.h>
06e1d8
 
9b746a
 #include "shell/cc-hostname-entry.h"
9b746a
 
9b746a
 #include "cc-info-resources.h"
9b746a
+#include "cc-subscription-details-dialog.h"
9b746a
+#include "cc-subscription-register-dialog.h"
9b746a
 #include "info-cleanup.h"
9b746a
 
9b746a
 #include <glib.h>
06e1d8
 #include <glib/gi18n.h>
06e1d8
 #include <gio/gio.h>
06e1d8
 #include <gio/gunixmounts.h>
06e1d8
 #include <gio/gdesktopappinfo.h>
06e1d8
 
06e1d8
 #include <glibtop/fsusage.h>
06e1d8
 #include <glibtop/mountlist.h>
06e1d8
 #include <glibtop/mem.h>
06e1d8
 #include <glibtop/sysinfo.h>
06e1d8
 
06e1d8
 #include <gdk/gdk.h>
06e1d8
 
06e1d8
 #ifdef GDK_WINDOWING_WAYLAND
06e1d8
 #include <gdk/gdkwayland.h>
06e1d8
 #endif
06e1d8
 #ifdef GDK_WINDOWING_X11
06e1d8
 #include <gdk/gdkx.h>
06e1d8
 #endif
06e1d8
 
06e1d8
 #include "gsd-disk-space-helper.h"
06e1d8
 
06e1d8
 #include "cc-info-overview-panel.h"
06e1d8
 
06e1d8
 
06e1d8
 typedef struct {
06e1d8
   /* Will be one or 2 GPU name strings, or "Unknown" */
06e1d8
   char *hardware_string;
06e1d8
 } GraphicsData;
06e1d8
 
06e1d8
 typedef struct
06e1d8
 {
06e1d8
   GtkWidget      *system_image;
06e1d8
   GtkWidget      *version_label;
06e1d8
   GtkWidget      *name_entry;
06e1d8
   GtkWidget      *memory_label;
06e1d8
   GtkWidget      *processor_label;
06e1d8
   GtkWidget      *os_name_label;
06e1d8
   GtkWidget      *os_type_label;
9b746a
   GtkWidget      *disk_label;
9b746a
   GtkWidget      *graphics_label;
9b746a
   GtkWidget      *virt_type_label;
9b746a
+  GtkWidget      *subscription_stack;
9b746a
+  GtkWidget      *details_button;
9b746a
+  GtkWidget      *register_button;
9b746a
+  GtkWidget      *updates_separator;
9b746a
   GtkWidget      *updates_button;
9b746a
 
9b746a
   /* Virtualisation labels */
06e1d8
   GtkWidget      *label8;
06e1d8
   GtkWidget      *grid1;
06e1d8
   GtkWidget      *label18;
06e1d8
 
06e1d8
   char           *gnome_version;
06e1d8
   char           *gnome_distributor;
06e1d8
   char           *gnome_date;
06e1d8
 
06e1d8
   GCancellable   *cancellable;
06e1d8
 
06e1d8
   /* Free space */
06e1d8
   GList          *primary_mounts;
9b746a
   guint64         total_bytes;
9b746a
 
9b746a
   GraphicsData   *graphics_data;
9b746a
+
9b746a
+  GDBusProxy     *subscription_proxy;
9b746a
 } CcInfoOverviewPanelPrivate;
9b746a
 
9b746a
 struct _CcInfoOverviewPanel
06e1d8
 {
06e1d8
  CcPanel parent_instance;
06e1d8
 
06e1d8
   /*< private >*/
06e1d8
  CcInfoOverviewPanelPrivate *priv;
06e1d8
 };
06e1d8
 
06e1d8
 static void get_primary_disc_info_start (CcInfoOverviewPanel *self);
06e1d8
 
06e1d8
 typedef struct
06e1d8
 {
06e1d8
   char *major;
06e1d8
   char *minor;
06e1d8
   char *micro;
06e1d8
   char *distributor;
06e1d8
   char *date;
06e1d8
   char **current;
06e1d8
 } VersionData;
06e1d8
 
06e1d8
 static void
06e1d8
 version_data_free (VersionData *data)
06e1d8
 {
06e1d8
   g_free (data->major);
06e1d8
   g_free (data->minor);
06e1d8
   g_free (data->micro);
06e1d8
   g_free (data->distributor);
06e1d8
   g_free (data->date);
06e1d8
@@ -559,61 +567,60 @@ get_primary_disc_info (CcInfoOverviewPanel *self)
06e1d8
     points = g_unix_mounts_get (NULL);
06e1d8
 
06e1d8
   for (p = points; p != NULL; p = p->next)
06e1d8
     {
06e1d8
       GUnixMountEntry *mount = p->data;
06e1d8
       const char *mount_path;
06e1d8
       const char *device_path;
06e1d8
 
06e1d8
       mount_path = g_unix_mount_get_mount_path (mount);
06e1d8
       device_path = g_unix_mount_get_device_path (mount);
06e1d8
 
06e1d8
       /* Do not count multiple mounts with same device_path, because it is
06e1d8
        * probably something like btrfs subvolume. Use only the first one in
06e1d8
        * order to count the real size. */
06e1d8
       if (gsd_should_ignore_unix_mount (mount) ||
06e1d8
           gsd_is_removable_mount (mount) ||
06e1d8
           g_str_has_prefix (mount_path, "/media/") ||
06e1d8
           g_str_has_prefix (mount_path, g_get_home_dir ()) ||
06e1d8
           g_hash_table_lookup (hash, device_path) != NULL)
06e1d8
         {
06e1d8
           g_unix_mount_free (mount);
06e1d8
           continue;
06e1d8
         }
06e1d8
 
06e1d8
       priv->primary_mounts = g_list_prepend (priv->primary_mounts, mount);
06e1d8
       g_hash_table_insert (hash, (gpointer) device_path, (gpointer) device_path);
06e1d8
     }
9b746a
   g_list_free (points);
9b746a
   g_hash_table_destroy (hash);
9b746a
 
9b746a
-  priv->cancellable = g_cancellable_new ();
9b746a
   get_primary_disc_info_start (self);
9b746a
 }
9b746a
 
06e1d8
 static char *
06e1d8
 get_cpu_info (const glibtop_sysinfo *info)
06e1d8
 {
06e1d8
   g_autoptr(GHashTable) counts = NULL;
06e1d8
   g_autoptr(GString) cpu = NULL;
06e1d8
   GHashTableIter iter;
06e1d8
   gpointer       key, value;
06e1d8
   int            i;
06e1d8
   int            j;
06e1d8
 
06e1d8
   counts = g_hash_table_new (g_str_hash, g_str_equal);
06e1d8
 
06e1d8
   /* count duplicates */
06e1d8
   for (i = 0; i != info->ncpu; ++i)
06e1d8
     {
06e1d8
       const char * const keys[] = { "model name", "cpu", "Processor" };
06e1d8
       char *model;
06e1d8
       int  *count;
06e1d8
 
06e1d8
       model = NULL;
06e1d8
 
06e1d8
       for (j = 0; model == NULL && j != G_N_ELEMENTS (keys); ++j)
06e1d8
         {
06e1d8
           model = g_hash_table_lookup (info->cpuinfo[i].values,
06e1d8
                                        keys[j]);
06e1d8
         }
06e1d8
 
06e1d8
@@ -766,60 +773,191 @@ info_overview_panel_setup_overview (CcInfoOverviewPanel *self)
06e1d8
   res = load_gnome_version (&priv->gnome_version,
06e1d8
                             &priv->gnome_distributor,
06e1d8
                             &priv->gnome_date);
06e1d8
   if (res)
06e1d8
     {
06e1d8
       g_autofree gchar *text = NULL;
06e1d8
       text = g_strdup_printf (_("Version %s"), priv->gnome_version);
06e1d8
       gtk_label_set_text (GTK_LABEL (priv->version_label), text);
06e1d8
     }
06e1d8
 
06e1d8
   glibtop_get_mem (&mem;;
06e1d8
   memory_text = g_format_size_full (mem.total, G_FORMAT_SIZE_IEC_UNITS);
06e1d8
   gtk_label_set_text (GTK_LABEL (priv->memory_label), memory_text ? memory_text : "");
06e1d8
 
06e1d8
   info = glibtop_get_sysinfo ();
06e1d8
 
06e1d8
   cpu_text = get_cpu_info (info);
06e1d8
   gtk_label_set_markup (GTK_LABEL (priv->processor_label), cpu_text ? cpu_text : "");
06e1d8
 
06e1d8
   os_type_text = get_os_type ();
06e1d8
   gtk_label_set_text (GTK_LABEL (priv->os_type_label), os_type_text ? os_type_text : "");
06e1d8
 
06e1d8
   os_name_text = get_os_name ();
06e1d8
   gtk_label_set_text (GTK_LABEL (priv->os_name_label), os_name_text ? os_name_text : "");
06e1d8
 
06e1d8
   get_primary_disc_info (self);
06e1d8
 
9b746a
   gtk_label_set_markup (GTK_LABEL (priv->graphics_label), priv->graphics_data->hardware_string);
9b746a
 }
9b746a
 
9b746a
+typedef enum {
9b746a
+  GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN,
9b746a
+  GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID,
9b746a
+  GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID,
9b746a
+  GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED,
9b746a
+  GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID,
9b746a
+  GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST
9b746a
+} GsdSubmanSubscriptionStatus;
9b746a
+
9b746a
+static gboolean
9b746a
+get_subscription_status (CcInfoOverviewPanel *self, GsdSubmanSubscriptionStatus *status)
9b746a
+{
9b746a
+  CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self);
9b746a
+  g_autoptr(GVariant) status_variant = NULL;
9b746a
+  guint32 u;
9b746a
+
9b746a
+  status_variant = g_dbus_proxy_get_cached_property (priv->subscription_proxy, "SubscriptionStatus");
9b746a
+  if (!status_variant)
9b746a
+    {
9b746a
+      g_debug ("Unable to get SubscriptionStatus property");
9b746a
+      return FALSE;
9b746a
+    }
9b746a
+
9b746a
+  g_variant_get (status_variant, "u", &u);
9b746a
+  *status = u;
9b746a
+
9b746a
+  return TRUE;
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+reload_subscription_status (CcInfoOverviewPanel *self)
9b746a
+{
9b746a
+  CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self);
9b746a
+  GsdSubmanSubscriptionStatus status;
9b746a
+
9b746a
+  if (priv->subscription_proxy == NULL)
9b746a
+    {
9b746a
+      gtk_widget_hide (priv->subscription_stack);
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  if (!get_subscription_status (self, &status))
9b746a
+    {
9b746a
+      gtk_widget_hide (priv->subscription_stack);
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  switch (status)
9b746a
+    {
9b746a
+    case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN:
9b746a
+    case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID:
9b746a
+    case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED:
9b746a
+    case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID:
9b746a
+      gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "not-registered");
9b746a
+      gtk_widget_set_sensitive (priv->updates_button, FALSE);
9b746a
+      break;
9b746a
+
9b746a
+    case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID:
9b746a
+      gtk_stack_set_visible_child_name (GTK_STACK (priv->subscription_stack), "registered");
9b746a
+      gtk_widget_set_sensitive (priv->updates_button, TRUE);
9b746a
+      break;
9b746a
+
9b746a
+    default:
9b746a
+      g_assert_not_reached ();
9b746a
+      break;
9b746a
+    }
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+on_details_button_clicked (GtkWidget           *widget,
9b746a
+                           CcInfoOverviewPanel *self)
9b746a
+{
9b746a
+  CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self);
9b746a
+  CcSubscriptionDetailsDialog *dialog;
9b746a
+  GtkWindow *toplevel;
9b746a
+
9b746a
+  dialog = cc_subscription_details_dialog_new (priv->subscription_proxy);
9b746a
+  toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
9b746a
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
9b746a
+
9b746a
+  gtk_dialog_run (GTK_DIALOG (dialog));
9b746a
+  gtk_widget_destroy (GTK_WIDGET (dialog));
9b746a
+
9b746a
+  reload_subscription_status (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+on_register_button_clicked (GtkWidget           *widget,
9b746a
+                            CcInfoOverviewPanel *self)
9b746a
+{
9b746a
+  CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self);
9b746a
+  CcSubscriptionRegisterDialog *dialog;
9b746a
+  GtkWindow *toplevel;
9b746a
+
9b746a
+  dialog = cc_subscription_register_dialog_new (priv->subscription_proxy);
9b746a
+  toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
9b746a
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
9b746a
+
9b746a
+  gtk_dialog_run (GTK_DIALOG (dialog));
9b746a
+  gtk_widget_destroy (GTK_WIDGET (dialog));
9b746a
+
9b746a
+  reload_subscription_status (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+info_overview_panel_setup_subscriptions (CcInfoOverviewPanel *self)
9b746a
+{
9b746a
+  CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self);
9b746a
+  g_autoptr(GError) error = NULL;
9b746a
+
9b746a
+  priv->subscription_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
9b746a
+                                                            G_DBUS_PROXY_FLAGS_NONE,
9b746a
+                                                            NULL,
9b746a
+                                                            "org.gnome.SettingsDaemon.Subscription",
9b746a
+                                                            "/org/gnome/SettingsDaemon/Subscription",
9b746a
+                                                            "org.gnome.SettingsDaemon.Subscription",
9b746a
+                                                            NULL, &error);
9b746a
+  if (error != NULL)
9b746a
+    {
9b746a
+      g_debug ("Unable to create a proxy for org.gnome.SettingsDaemon.Subscription: %s",
9b746a
+               error->message);
9b746a
+      reload_subscription_status (self);
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  g_signal_connect (priv->details_button, "clicked", G_CALLBACK (on_details_button_clicked), self);
9b746a
+  g_signal_connect (priv->register_button, "clicked", G_CALLBACK (on_register_button_clicked), self);
9b746a
+
9b746a
+  reload_subscription_status (self);
9b746a
+}
9b746a
+
9b746a
 static gboolean
9b746a
 does_gnome_software_exist (void)
9b746a
 {
06e1d8
   return g_file_test (BINDIR "/gnome-software", G_FILE_TEST_EXISTS);
06e1d8
 }
06e1d8
 
06e1d8
 static gboolean
06e1d8
 does_gpk_update_viewer_exist (void)
06e1d8
 {
06e1d8
   return g_file_test (BINDIR "/gpk-update-viewer", G_FILE_TEST_EXISTS);
06e1d8
 }
06e1d8
 
06e1d8
 static void
06e1d8
 on_updates_button_clicked (GtkWidget           *widget,
06e1d8
                            CcInfoOverviewPanel *self)
06e1d8
 {
06e1d8
   g_autoptr(GError) error = NULL;
06e1d8
   gboolean ret;
06e1d8
   g_auto(GStrv) argv = NULL;
06e1d8
 
06e1d8
   argv = g_new0 (gchar *, 3);
06e1d8
   if (does_gnome_software_exist ())
06e1d8
     {
06e1d8
       argv[0] = g_build_filename (BINDIR, "gnome-software", NULL);
06e1d8
       argv[1] = g_strdup_printf ("--mode=updates");
06e1d8
     }
06e1d8
   else
06e1d8
     {
06e1d8
       argv[0] = g_build_filename (BINDIR, "gpk-update-viewer", NULL);
06e1d8
     }
06e1d8
@@ -829,88 +967,103 @@ on_updates_button_clicked (GtkWidget           *widget,
06e1d8
 }
06e1d8
 
06e1d8
 static void
06e1d8
 cc_info_overview_panel_dispose (GObject *object)
06e1d8
 {
06e1d8
   CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (CC_INFO_OVERVIEW_PANEL (object));
06e1d8
 
06e1d8
   g_clear_pointer (&priv->graphics_data, graphics_data_free);
06e1d8
 
06e1d8
   G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->dispose (object);
06e1d8
 }
06e1d8
 
06e1d8
 static void
06e1d8
 cc_info_overview_panel_finalize (GObject *object)
06e1d8
 {
06e1d8
   CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (CC_INFO_OVERVIEW_PANEL (object));
06e1d8
 
06e1d8
   if (priv->cancellable)
06e1d8
     {
06e1d8
       g_cancellable_cancel (priv->cancellable);
06e1d8
       g_clear_object (&priv->cancellable);
06e1d8
     }
06e1d8
 
06e1d8
   if (priv->primary_mounts)
06e1d8
     g_list_free_full (priv->primary_mounts, (GDestroyNotify) g_unix_mount_free);
06e1d8
 
06e1d8
   g_free (priv->gnome_version);
9b746a
   g_free (priv->gnome_date);
9b746a
   g_free (priv->gnome_distributor);
9b746a
 
9b746a
+  g_clear_object (&priv->subscription_proxy);
9b746a
+
9b746a
   G_OBJECT_CLASS (cc_info_overview_panel_parent_class)->finalize (object);
9b746a
 }
9b746a
 
06e1d8
 static void
06e1d8
 cc_info_overview_panel_class_init (CcInfoOverviewPanelClass *klass)
06e1d8
 {
06e1d8
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
06e1d8
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
06e1d8
 
06e1d8
   object_class->finalize = cc_info_overview_panel_finalize;
06e1d8
   object_class->dispose = cc_info_overview_panel_dispose;
06e1d8
 
06e1d8
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/info-overview.ui");
06e1d8
 
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, system_image);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, version_label);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, name_entry);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, memory_label);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, processor_label);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_name_label);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, os_type_label);
9b746a
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, disk_label);
9b746a
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, graphics_label);
9b746a
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, virt_type_label);
9b746a
+  gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, subscription_stack);
9b746a
+  gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, details_button);
9b746a
+  gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, register_button);
9b746a
+  gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_separator);
9b746a
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, updates_button);
9b746a
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label8);
9b746a
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, grid1);
06e1d8
   gtk_widget_class_bind_template_child_private (widget_class, CcInfoOverviewPanel, label18);
06e1d8
 
06e1d8
   g_type_ensure (CC_TYPE_HOSTNAME_ENTRY);
06e1d8
 }
06e1d8
 
06e1d8
 static void
06e1d8
 cc_info_overview_panel_init (CcInfoOverviewPanel *self)
06e1d8
 {
06e1d8
   CcInfoOverviewPanelPrivate *priv = cc_info_overview_panel_get_instance_private (self);
06e1d8
 
06e1d8
   gtk_widget_init_template (GTK_WIDGET (self));
9b746a
 
9b746a
   g_resources_register (cc_info_get_resource ());
9b746a
 
9b746a
+  priv->cancellable = g_cancellable_new ();
9b746a
+
9b746a
   priv->graphics_data = get_graphics_data ();
9b746a
 
9b746a
   if (does_gnome_software_exist () || does_gpk_update_viewer_exist ())
9b746a
     g_signal_connect (priv->updates_button, "clicked", G_CALLBACK (on_updates_button_clicked), self);
9b746a
   else
9b746a
-    gtk_widget_destroy (priv->updates_button);
9b746a
+    gtk_widget_hide (priv->updates_button);
9b746a
 
9b746a
   info_overview_panel_setup_overview (self);
9b746a
   info_overview_panel_setup_virt (self);
9b746a
+  info_overview_panel_setup_subscriptions (self);
9b746a
+
9b746a
+  /* show separator when both items are visible */
9b746a
+  if (gtk_widget_get_visible (priv->subscription_stack) && gtk_widget_get_visible (priv->updates_button))
9b746a
+    gtk_widget_show (priv->updates_separator);
9b746a
+  else
9b746a
+    gtk_widget_hide (priv->updates_separator);
9b746a
 }
9b746a
 
9b746a
 GtkWidget *
06e1d8
 cc_info_overview_panel_new (void)
06e1d8
 {
06e1d8
   return g_object_new (CC_TYPE_INFO_OVERVIEW_PANEL,
06e1d8
                        NULL);
06e1d8
 }
9b746a
diff --git a/panels/info/cc-subscription-details-dialog.c b/panels/info/cc-subscription-details-dialog.c
9b746a
new file mode 100644
9b746a
index 000000000..1931ced81
9b746a
--- /dev/null
9b746a
+++ b/panels/info/cc-subscription-details-dialog.c
9b746a
@@ -0,0 +1,407 @@
9b746a
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
9b746a
+ *
9b746a
+ * Copyright 2019  Red Hat, Inc,
9b746a
+ *
9b746a
+ * This program is free software; you can redistribute it and/or modify
9b746a
+ * it under the terms of the GNU General Public License as published by
9b746a
+ * the Free Software Foundation; either version 2 of the License, or
9b746a
+ * (at your option) any later version.
9b746a
+ *
9b746a
+ * This program is distributed in the hope that it will be useful,
9b746a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9b746a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9b746a
+ * GNU General Public License for more details.
9b746a
+ *
9b746a
+ * You should have received a copy of the GNU General Public License
9b746a
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9b746a
+ *
9b746a
+ * Written by: Kalev Lember <klember@redhat.com>
9b746a
+ */
9b746a
+
9b746a
+#include "config.h"
9b746a
+
9b746a
+#include <glib.h>
9b746a
+#include <glib/gi18n.h>
9b746a
+#include <gtk/gtk.h>
9b746a
+
9b746a
+#include "cc-subscription-details-dialog.h"
9b746a
+
9b746a
+#define DBUS_TIMEOUT 300000 /* 5 minutes */
9b746a
+
9b746a
+typedef enum {
9b746a
+  DIALOG_STATE_SHOW_DETAILS,
9b746a
+  DIALOG_STATE_UNREGISTER,
9b746a
+  DIALOG_STATE_UNREGISTERING
9b746a
+} DialogState;
9b746a
+
9b746a
+struct _CcSubscriptionDetailsDialog
9b746a
+{
9b746a
+  GtkDialog     parent_instance;
9b746a
+
9b746a
+  DialogState   state;
9b746a
+  GCancellable *cancellable;
9b746a
+  GDBusProxy   *subscription_proxy;
9b746a
+  GPtrArray    *products;
9b746a
+
9b746a
+  /* template widgets */
9b746a
+  GtkButton    *back_button;
9b746a
+  GtkSpinner   *spinner;
9b746a
+  GtkButton    *header_unregister_button;
9b746a
+  GtkRevealer  *notification_revealer;
9b746a
+  GtkLabel     *error_label;
9b746a
+  GtkStack     *stack;
9b746a
+  GtkBox       *products_box1;
9b746a
+  GtkBox       *products_box2;
9b746a
+  GtkButton    *unregister_button;
9b746a
+};
9b746a
+
9b746a
+G_DEFINE_TYPE (CcSubscriptionDetailsDialog, cc_subscription_details_dialog, GTK_TYPE_DIALOG);
9b746a
+
9b746a
+typedef struct
9b746a
+{
9b746a
+  gchar *product_name;
9b746a
+  gchar *product_id;
9b746a
+  gchar *version;
9b746a
+  gchar *arch;
9b746a
+  gchar *status;
9b746a
+  gchar *starts;
9b746a
+  gchar *ends;
9b746a
+} ProductData;
9b746a
+
9b746a
+static void
9b746a
+product_data_free (ProductData *product)
9b746a
+{
9b746a
+  g_free (product->product_name);
9b746a
+  g_free (product->product_id);
9b746a
+  g_free (product->version);
9b746a
+  g_free (product->arch);
9b746a
+  g_free (product->status);
9b746a
+  g_free (product->starts);
9b746a
+  g_free (product->ends);
9b746a
+  g_free (product);
9b746a
+}
9b746a
+
9b746a
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (ProductData, product_data_free);
9b746a
+
9b746a
+static void
9b746a
+add_product_row (GtkGrid *product_grid, const gchar *name, const gchar *value, gint top_attach)
9b746a
+{
9b746a
+  GtkWidget *w;
9b746a
+
9b746a
+  w = gtk_label_new (name);
9b746a
+  gtk_style_context_add_class (gtk_widget_get_style_context (w), "dim-label");
9b746a
+  gtk_grid_attach (product_grid, w, 0, top_attach, 1, 1);
9b746a
+  gtk_widget_set_halign (w, GTK_ALIGN_END);
9b746a
+  gtk_widget_show (w);
9b746a
+
9b746a
+  if (value == NULL)
9b746a
+    value = _("Unknown");
9b746a
+
9b746a
+  w = gtk_label_new (value);
9b746a
+  gtk_grid_attach (product_grid, w, 1, top_attach, 1, 1);
9b746a
+  gtk_widget_set_halign (w, GTK_ALIGN_START);
9b746a
+  gtk_widget_set_hexpand (w, TRUE);
9b746a
+  gtk_widget_show (w);
9b746a
+}
9b746a
+
9b746a
+static GtkWidget *
9b746a
+add_product (CcSubscriptionDetailsDialog *self, ProductData *product)
9b746a
+{
9b746a
+  GtkGrid *product_grid;
9b746a
+  const gchar *status_text;
9b746a
+
9b746a
+  if (g_strcmp0 (product->status, "subscribed") == 0)
9b746a
+    status_text = _("Subscribed");
9b746a
+  else
9b746a
+    status_text = _("Not Subscribed (Not supported by a valid subscription.)");
9b746a
+
9b746a
+  product_grid = GTK_GRID (gtk_grid_new ());
9b746a
+  gtk_grid_set_column_spacing (product_grid, 12);
9b746a
+  gtk_grid_set_row_spacing (product_grid, 6);
9b746a
+  gtk_widget_set_margin_top (GTK_WIDGET (product_grid), 18);
9b746a
+  gtk_widget_set_margin_bottom (GTK_WIDGET (product_grid), 12);
9b746a
+  gtk_widget_show (GTK_WIDGET (product_grid));
9b746a
+
9b746a
+  add_product_row (product_grid, _("Product Name"), product->product_name, 0);
9b746a
+  add_product_row (product_grid, _("Product ID"), product->product_id, 1);
9b746a
+  add_product_row (product_grid, _("Version"), product->version, 2);
9b746a
+  add_product_row (product_grid, _("Arch"), product->arch, 3);
9b746a
+  add_product_row (product_grid, _("Status"), status_text, 4);
9b746a
+  add_product_row (product_grid, _("Starts"), product->starts, 5);
9b746a
+  add_product_row (product_grid, _("Ends"), product->ends, 6);
9b746a
+
9b746a
+  return GTK_WIDGET (product_grid);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+remove_all_children (GtkContainer *container)
9b746a
+{
9b746a
+  g_autoptr(GList) list = gtk_container_get_children (container);
9b746a
+
9b746a
+  for (GList *l = list; l != NULL; l = l->next)
9b746a
+    gtk_container_remove (container, (GtkWidget *) l->data);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+dialog_reload (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  GtkHeaderBar *header = GTK_HEADER_BAR (gtk_dialog_get_header_bar (GTK_DIALOG (self)));
9b746a
+
9b746a
+  switch (self->state)
9b746a
+    {
9b746a
+    case DIALOG_STATE_SHOW_DETAILS:
9b746a
+      gtk_header_bar_set_show_close_button (header, TRUE);
9b746a
+
9b746a
+      gtk_window_set_title (GTK_WINDOW (self), _("Registration Details"));
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->header_unregister_button), TRUE);
9b746a
+
9b746a
+      gtk_widget_hide (GTK_WIDGET (self->back_button));
9b746a
+      gtk_widget_hide (GTK_WIDGET (self->header_unregister_button));
9b746a
+
9b746a
+      gtk_stack_set_visible_child_name (self->stack, "show-details");
9b746a
+      break;
9b746a
+
9b746a
+    case DIALOG_STATE_UNREGISTER:
9b746a
+      gtk_header_bar_set_show_close_button (header, FALSE);
9b746a
+
9b746a
+      gtk_window_set_title (GTK_WINDOW (self), _("Unregister System"));
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->header_unregister_button), TRUE);
9b746a
+
9b746a
+      gtk_widget_show (GTK_WIDGET (self->back_button));
9b746a
+      gtk_widget_show (GTK_WIDGET (self->header_unregister_button));
9b746a
+
9b746a
+      gtk_stack_set_visible_child_name (self->stack, "unregister");
9b746a
+      break;
9b746a
+
9b746a
+    case DIALOG_STATE_UNREGISTERING:
9b746a
+      gtk_header_bar_set_show_close_button (header, FALSE);
9b746a
+
9b746a
+      gtk_window_set_title (GTK_WINDOW (self), _("Unregistering System…"));
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->header_unregister_button), FALSE);
9b746a
+
9b746a
+      gtk_widget_show (GTK_WIDGET (self->back_button));
9b746a
+      gtk_widget_show (GTK_WIDGET (self->header_unregister_button));
9b746a
+
9b746a
+      gtk_stack_set_visible_child_name (self->stack, "unregister");
9b746a
+      break;
9b746a
+
9b746a
+    default:
9b746a
+      g_assert_not_reached ();
9b746a
+      break;
9b746a
+    }
9b746a
+
9b746a
+  remove_all_children (GTK_CONTAINER (self->products_box1));
9b746a
+  remove_all_children (GTK_CONTAINER (self->products_box2));
9b746a
+
9b746a
+  if (self->products == NULL || self->products->len == 0)
9b746a
+    {
9b746a
+      /* the widgets are duplicate to allow sliding between two stack pages */
9b746a
+      GtkWidget *w1 = gtk_label_new (_("No installed products detected."));
9b746a
+      GtkWidget *w2 = gtk_label_new (_("No installed products detected."));
9b746a
+      gtk_widget_show (w1);
9b746a
+      gtk_widget_show (w2);
9b746a
+      gtk_container_add (GTK_CONTAINER (self->products_box1), w1);
9b746a
+      gtk_container_add (GTK_CONTAINER (self->products_box2), w2);
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  for (guint i = 0; i < self->products->len; i++)
9b746a
+    {
9b746a
+      ProductData *product = g_ptr_array_index (self->products, i);
9b746a
+      /* the widgets are duplicate to allow sliding between two stack pages */
9b746a
+      GtkWidget *w1 = add_product (self, product);
9b746a
+      GtkWidget *w2 = add_product (self, product);
9b746a
+      gtk_container_add (GTK_CONTAINER (self->products_box1), w1);
9b746a
+      gtk_container_add (GTK_CONTAINER (self->products_box2), w2);
9b746a
+    }
9b746a
+}
9b746a
+
9b746a
+static ProductData *
9b746a
+parse_product_variant (GVariant *product_variant)
9b746a
+{
9b746a
+  g_autoptr(ProductData) product = g_new0 (ProductData, 1);
9b746a
+  g_auto(GVariantDict) dict;
9b746a
+
9b746a
+  g_variant_dict_init (&dict, product_variant);
9b746a
+
9b746a
+  g_variant_dict_lookup (&dict, "product-name", "s", &product->product_name);
9b746a
+  g_variant_dict_lookup (&dict, "product-id", "s", &product->product_id);
9b746a
+  g_variant_dict_lookup (&dict, "version", "s", &product->version);
9b746a
+  g_variant_dict_lookup (&dict, "arch", "s", &product->arch);
9b746a
+  g_variant_dict_lookup (&dict, "status", "s", &product->status);
9b746a
+  g_variant_dict_lookup (&dict, "starts", "s", &product->starts);
9b746a
+  g_variant_dict_lookup (&dict, "ends", "s", &product->ends);
9b746a
+
9b746a
+  return g_steal_pointer (&product);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+load_installed_products (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  GVariantIter iter_array;
9b746a
+  GVariant *child;
9b746a
+  g_autoptr(GError) error = NULL;
9b746a
+  g_autoptr(GVariant) installed_products_variant = NULL;
9b746a
+
9b746a
+  installed_products_variant = g_dbus_proxy_get_cached_property (self->subscription_proxy, "InstalledProducts");
9b746a
+  if (installed_products_variant == NULL)
9b746a
+    {
9b746a
+      g_debug ("Unable to get InstalledProducts dbus property");
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  g_ptr_array_set_size (self->products, 0);
9b746a
+
9b746a
+  g_variant_iter_init (&iter_array, installed_products_variant);
9b746a
+  while ((child = g_variant_iter_next_value (&iter_array)) != NULL)
9b746a
+    {
9b746a
+      g_autoptr(GVariant) product_variant = g_steal_pointer (&child);
9b746a
+      g_ptr_array_add (self->products, parse_product_variant (product_variant));
9b746a
+    }
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+unregistration_done_cb (GObject      *source_object,
9b746a
+                        GAsyncResult *res,
9b746a
+                        gpointer      user_data)
9b746a
+{
9b746a
+  CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) user_data;
9b746a
+  g_autoptr(GVariant) results = NULL;
9b746a
+  g_autoptr(GError) error = NULL;
9b746a
+
9b746a
+  results = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
9b746a
+                                      res,
9b746a
+                                      &error);
9b746a
+  if (results == NULL)
9b746a
+    {
9b746a
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
9b746a
+        return;
9b746a
+
9b746a
+      g_dbus_error_strip_remote_error (error);
9b746a
+      gtk_label_set_text (self->error_label, error->message);
9b746a
+      gtk_revealer_set_reveal_child (self->notification_revealer, TRUE);
9b746a
+
9b746a
+      gtk_spinner_stop (self->spinner);
9b746a
+
9b746a
+      self->state = DIALOG_STATE_UNREGISTER;
9b746a
+      dialog_reload (self);
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  gtk_spinner_stop (self->spinner);
9b746a
+
9b746a
+  gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+header_unregister_button_clicked_cb (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  gtk_spinner_start (self->spinner);
9b746a
+
9b746a
+  self->state = DIALOG_STATE_UNREGISTERING;
9b746a
+  dialog_reload (self);
9b746a
+
9b746a
+  g_dbus_proxy_call (self->subscription_proxy,
9b746a
+                     "Unregister",
9b746a
+                     NULL,
9b746a
+                     G_DBUS_CALL_FLAGS_NONE,
9b746a
+                     DBUS_TIMEOUT,
9b746a
+                     self->cancellable,
9b746a
+                     unregistration_done_cb,
9b746a
+                     self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+back_button_clicked_cb (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  gtk_spinner_stop (self->spinner);
9b746a
+
9b746a
+  self->state = DIALOG_STATE_SHOW_DETAILS;
9b746a
+  dialog_reload (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+unregister_button_clicked_cb (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  self->state = DIALOG_STATE_UNREGISTER;
9b746a
+  dialog_reload (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+dismiss_notification (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  gtk_revealer_set_reveal_child (self->notification_revealer, FALSE);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_details_dialog_init (CcSubscriptionDetailsDialog *self)
9b746a
+{
9b746a
+  gtk_widget_init_template (GTK_WIDGET (self));
9b746a
+
9b746a
+  self->cancellable = g_cancellable_new ();
9b746a
+  self->products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free);
9b746a
+  self->state = DIALOG_STATE_SHOW_DETAILS;
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_details_dialog_dispose (GObject *obj)
9b746a
+{
9b746a
+  CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) obj;
9b746a
+
9b746a
+  g_cancellable_cancel (self->cancellable);
9b746a
+  g_clear_object (&self->cancellable);
9b746a
+  g_clear_object (&self->subscription_proxy);
9b746a
+
9b746a
+  G_OBJECT_CLASS (cc_subscription_details_dialog_parent_class)->dispose (obj);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_details_dialog_finalize (GObject *obj)
9b746a
+{
9b746a
+  CcSubscriptionDetailsDialog *self = (CcSubscriptionDetailsDialog *) obj;
9b746a
+
9b746a
+  g_clear_pointer (&self->products, g_ptr_array_unref);
9b746a
+
9b746a
+  G_OBJECT_CLASS (cc_subscription_details_dialog_parent_class)->finalize (obj);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_details_dialog_class_init (CcSubscriptionDetailsDialogClass *klass)
9b746a
+{
9b746a
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
9b746a
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
9b746a
+
9b746a
+  object_class->dispose = cc_subscription_details_dialog_dispose;
9b746a
+  object_class->finalize = cc_subscription_details_dialog_finalize;
9b746a
+
9b746a
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/cc-subscription-details-dialog.ui");
9b746a
+
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, back_button);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, spinner);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, header_unregister_button);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, notification_revealer);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, error_label);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, stack);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box1);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, products_box2);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionDetailsDialog, unregister_button);
9b746a
+
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, back_button_clicked_cb);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, header_unregister_button_clicked_cb);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, unregister_button_clicked_cb);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, dismiss_notification);
9b746a
+}
9b746a
+
9b746a
+CcSubscriptionDetailsDialog *
9b746a
+cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy)
9b746a
+{
9b746a
+  CcSubscriptionDetailsDialog *self;
9b746a
+
9b746a
+  self = g_object_new (CC_TYPE_SUBSCRIPTION_DETAILS_DIALOG, "use-header-bar", TRUE, NULL);
9b746a
+  self->subscription_proxy = g_object_ref (subscription_proxy);
9b746a
+
9b746a
+  load_installed_products (self);
9b746a
+  dialog_reload (self);
9b746a
+
9b746a
+  return self;
9b746a
+}
9b746a
diff --git a/panels/info/cc-subscription-details-dialog.h b/panels/info/cc-subscription-details-dialog.h
9b746a
new file mode 100644
9b746a
index 000000000..a61a22838
9b746a
--- /dev/null
9b746a
+++ b/panels/info/cc-subscription-details-dialog.h
9b746a
@@ -0,0 +1,32 @@
9b746a
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
9b746a
+ *
9b746a
+ * Copyright 2019  Red Hat, Inc,
9b746a
+ *
9b746a
+ * This program is free software; you can redistribute it and/or modify
9b746a
+ * it under the terms of the GNU General Public License as published by
9b746a
+ * the Free Software Foundation; either version 2 of the License, or
9b746a
+ * (at your option) any later version.
9b746a
+ *
9b746a
+ * This program is distributed in the hope that it will be useful,
9b746a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9b746a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9b746a
+ * GNU General Public License for more details.
9b746a
+ *
9b746a
+ * You should have received a copy of the GNU General Public License
9b746a
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9b746a
+ *
9b746a
+ * Written by: Kalev Lember <klember@redhat.com>
9b746a
+ */
9b746a
+
9b746a
+#pragma once
9b746a
+
9b746a
+#include <gtk/gtk.h>
9b746a
+
9b746a
+G_BEGIN_DECLS
9b746a
+
9b746a
+#define CC_TYPE_SUBSCRIPTION_DETAILS_DIALOG (cc_subscription_details_dialog_get_type ())
9b746a
+G_DECLARE_FINAL_TYPE (CcSubscriptionDetailsDialog, cc_subscription_details_dialog, CC, SUBSCRIPTION_DETAILS_DIALOG, GtkDialog)
9b746a
+
9b746a
+CcSubscriptionDetailsDialog *cc_subscription_details_dialog_new (GDBusProxy *subscription_proxy);
9b746a
+
9b746a
+G_END_DECLS
9b746a
diff --git a/panels/info/cc-subscription-details-dialog.ui b/panels/info/cc-subscription-details-dialog.ui
9b746a
new file mode 100644
9b746a
index 000000000..6f0b16930
9b746a
--- /dev/null
9b746a
+++ b/panels/info/cc-subscription-details-dialog.ui
9b746a
@@ -0,0 +1,248 @@
9b746a
+
9b746a
+<interface>
9b746a
+  <template class="CcSubscriptionDetailsDialog" parent="GtkDialog">
9b746a
+    <property name="can_focus">False</property>
9b746a
+    <property name="resizable">False</property>
9b746a
+    <property name="modal">True</property>
9b746a
+    <property name="destroy_with_parent">True</property>
9b746a
+    <property name="type_hint">dialog</property>
9b746a
+    <property name="title" translatable="yes">Registration Details</property>
9b746a
+    <property name="use_header_bar">1</property>
9b746a
+    <child internal-child="headerbar">
9b746a
+      <object class="GtkHeaderBar">
9b746a
+        <property name="visible">True</property>
9b746a
+        <property name="can_focus">False</property>
9b746a
+        <property name="show_close_button">False</property>
9b746a
+        <child>
9b746a
+          <object class="GtkButton" id="back_button">
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="can_focus">True</property>
9b746a
+            <property name="receives_default">True</property>
9b746a
+            <property name="valign">center</property>
9b746a
+            <signal name="clicked" handler="back_button_clicked_cb" object="CcSubscriptionDetailsDialog" swapped="yes"/>
9b746a
+            <child>
9b746a
+              <object class="GtkImage">
9b746a
+                <property name="visible">True</property>
9b746a
+                <property name="can_focus">False</property>
9b746a
+                <property name="icon_name">go-previous-symbolic</property>
9b746a
+              </object>
9b746a
+            </child>
9b746a
+            <style>
9b746a
+              <class name="image-button"/>
9b746a
+            </style>
9b746a
+          </object>
9b746a
+        </child>
9b746a
+        <child>
9b746a
+          <object class="GtkButton" id="header_unregister_button">
9b746a
+            <property name="label" translatable="yes">_Unregister</property>
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="can_focus">True</property>
9b746a
+            <property name="can_default">True</property>
9b746a
+            <property name="has_default">True</property>
9b746a
+            <property name="receives_default">True</property>
9b746a
+            <property name="use_action_appearance">False</property>
9b746a
+            <property name="use_underline">True</property>
9b746a
+            <property name="valign">center</property>
9b746a
+            <signal name="clicked" handler="header_unregister_button_clicked_cb" object="CcSubscriptionDetailsDialog" swapped="yes"/>
9b746a
+            <style>
9b746a
+              <class name="text-button"/>
9b746a
+              <class name="destructive-action"/>
9b746a
+            </style>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="pack_type">end</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+        <child>
9b746a
+          <object class="GtkSpinner" id="spinner">
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="can_focus">False</property>
9b746a
+            <property name="valign">center</property>
9b746a
+            <property name="margin_start">6</property>
9b746a
+            <property name="margin_end">6</property>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="pack_type">end</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+      </object>
9b746a
+    </child>
9b746a
+    <child internal-child="vbox">
9b746a
+      <object class="GtkBox">
9b746a
+        <property name="visible">True</property>
9b746a
+        <property name="can_focus">False</property>
9b746a
+        <property name="orientation">vertical</property>
9b746a
+        <property name="border_width">0</property>
9b746a
+        <child>
9b746a
+          <object class="GtkOverlay" id="overlay">
9b746a
+            <property name="visible">True</property>
9b746a
+            <child type="overlay">
9b746a
+              <object class="GtkRevealer" id="notification_revealer">
9b746a
+                <property name="visible">True</property>
9b746a
+                <property name="halign">fill</property>
9b746a
+                <property name="hexpand">True</property>
9b746a
+                <property name="margin_start">20</property>
9b746a
+                <property name="margin_end">20</property>
9b746a
+                <property name="valign">start</property>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="spacing">6</property>
9b746a
+                    <style>
9b746a
+                      <class name="app-notification"/>
9b746a
+                    </style>
9b746a
+                    <child>
9b746a
+                      <object class="GtkBox">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="orientation">vertical</property>
9b746a
+                        <property name="margin_start">6</property>
9b746a
+                        <property name="margin_end">6</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                        <property name="halign">start</property>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <property name="wrap">True</property>
9b746a
+                            <property name="label" translatable="yes">Failed to Unregister System</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="weight" value="bold"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="error_label">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <property name="wrap">True</property>
9b746a
+                            <property name="wrap_mode">word-char</property>
9b746a
+                            <property name="label">Unable to reach developers.redhat.com. Please try again later.</property>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkButton" id="dismiss_button">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="valign">start</property>
9b746a
+                        <signal name="clicked" handler="dismiss_notification" object="CcSubscriptionDetailsDialog" swapped="yes"/>
9b746a
+                        <style>
9b746a
+                          <class name="flat"/>
9b746a
+                        </style>
9b746a
+                        <child>
9b746a
+                          <object class="GtkImage">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="icon_name">window-close-symbolic</property>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                </child>
9b746a
+              </object>
9b746a
+            </child>
9b746a
+            <child>
9b746a
+              <object class="GtkStack" id="stack">
9b746a
+                <property name="visible">True</property>
9b746a
+                <property name="can_focus">False</property>
9b746a
+                <property name="transition-type">slide-left-right</property>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="orientation">vertical</property>
9b746a
+                    <property name="margin_top">24</property>
9b746a
+                    <property name="margin_start">32</property>
9b746a
+                    <property name="margin_end">32</property>
9b746a
+                    <property name="margin_bottom">20</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkLabel">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">False</property>
9b746a
+                        <property name="label" translatable="yes">Registration with Red Hat allows this system to receive software updates.</property>
9b746a
+                        <property name="width_chars">45</property>
9b746a
+                        <property name="max_width_chars">45</property>
9b746a
+                        <property name="xalign">0</property>
9b746a
+                        <property name="halign">start</property>
9b746a
+                        <property name="wrap">True</property>
9b746a
+                        <style>
9b746a
+                          <class name="dim-label"/>
9b746a
+                        </style>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkBox" id="products_box1">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="orientation">vertical</property>
9b746a
+                        <property name="margin_top">6</property>
9b746a
+                        <property name="margin_bottom">6</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkButton" id="unregister_button">
9b746a
+                        <property name="label" translatable="yes">_Unregister…</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="use_underline">True</property>
9b746a
+                        <property name="receives_default">True</property>
9b746a
+                        <property name="use_action_appearance">False</property>
9b746a
+                        <property name="halign">end</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <signal name="clicked" handler="unregister_button_clicked_cb" object="CcSubscriptionDetailsDialog" swapped="yes"/>
9b746a
+                        <style>
9b746a
+                          <class name="text-button"/>
9b746a
+                        </style>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="name">show-details</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="orientation">vertical</property>
9b746a
+                    <property name="margin_top">24</property>
9b746a
+                    <property name="margin_start">32</property>
9b746a
+                    <property name="margin_end">32</property>
9b746a
+                    <property name="margin_bottom">20</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkLabel">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">False</property>
9b746a
+                        <property name="label" translatable="yes">Warning: unregistering this system will result in it no longer receiving software updates.</property>
9b746a
+                        <property name="width_chars">45</property>
9b746a
+                        <property name="max_width_chars">45</property>
9b746a
+                        <property name="xalign">0</property>
9b746a
+                        <property name="halign">start</property>
9b746a
+                        <property name="wrap">True</property>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkBox" id="products_box2">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="orientation">vertical</property>
9b746a
+                        <property name="margin_top">6</property>
9b746a
+                        <property name="margin_bottom">6</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="name">unregister</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+              </object>
9b746a
+            </child>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="expand">False</property>
9b746a
+            <property name="fill">True</property>
9b746a
+            <property name="position">0</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+      </object>
9b746a
+    </child>
9b746a
+  </template>
9b746a
+</interface>
9b746a
diff --git a/panels/info/cc-subscription-register-dialog.c b/panels/info/cc-subscription-register-dialog.c
9b746a
new file mode 100644
9b746a
index 000000000..d7a17cc99
9b746a
--- /dev/null
9b746a
+++ b/panels/info/cc-subscription-register-dialog.c
9b746a
@@ -0,0 +1,403 @@
9b746a
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
9b746a
+ *
9b746a
+ * Copyright 2019  Red Hat, Inc,
9b746a
+ *
9b746a
+ * This program is free software; you can redistribute it and/or modify
9b746a
+ * it under the terms of the GNU General Public License as published by
9b746a
+ * the Free Software Foundation; either version 2 of the License, or
9b746a
+ * (at your option) any later version.
9b746a
+ *
9b746a
+ * This program is distributed in the hope that it will be useful,
9b746a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9b746a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9b746a
+ * GNU General Public License for more details.
9b746a
+ *
9b746a
+ * You should have received a copy of the GNU General Public License
9b746a
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9b746a
+ *
9b746a
+ * Written by: Kalev Lember <klember@redhat.com>
9b746a
+ */
9b746a
+
9b746a
+#include "config.h"
9b746a
+
9b746a
+#include <glib.h>
9b746a
+#include <glib/gi18n.h>
9b746a
+#include <gtk/gtk.h>
9b746a
+
9b746a
+#include "cc-subscription-register-dialog.h"
9b746a
+
9b746a
+#define DBUS_TIMEOUT 300000 /* 5 minutes */
9b746a
+#define SERVER_URL "subscription.rhsm.redhat.com"
9b746a
+
9b746a
+typedef enum {
9b746a
+  DIALOG_STATE_REGISTER,
9b746a
+  DIALOG_STATE_REGISTERING
9b746a
+} DialogState;
9b746a
+
9b746a
+static void dialog_validate (CcSubscriptionRegisterDialog *self);
9b746a
+
9b746a
+struct _CcSubscriptionRegisterDialog
9b746a
+{
9b746a
+  GtkDialog       parent_instance;
9b746a
+
9b746a
+  DialogState     state;
9b746a
+  GCancellable   *cancellable;
9b746a
+  GDBusProxy     *subscription_proxy;
9b746a
+  gboolean        valid;
9b746a
+
9b746a
+  /* template widgets */
9b746a
+  GtkSpinner     *spinner;
9b746a
+  GtkButton      *register_button;
9b746a
+  GtkRevealer    *notification_revealer;
9b746a
+  GtkLabel       *error_label;
9b746a
+  GtkRadioButton *default_url_radio;
9b746a
+  GtkRadioButton *custom_url_radio;
9b746a
+  GtkRadioButton *register_radio;
9b746a
+  GtkRadioButton *register_with_activation_keys_radio;
9b746a
+  GtkStack       *stack;
9b746a
+  GtkGrid        *register_grid;
9b746a
+  GtkGrid        *register_with_activation_keys_grid;
9b746a
+  GtkEntry       *url_label;
9b746a
+  GtkEntry       *url_entry;
9b746a
+  GtkEntry       *login_entry;
9b746a
+  GtkEntry       *password_entry;
9b746a
+  GtkEntry       *activation_keys_entry;
9b746a
+  GtkLabel       *organization_label;
9b746a
+  GtkEntry       *organization_entry;
9b746a
+  GtkEntry       *organization_entry_with_activation_keys;
9b746a
+};
9b746a
+
9b746a
+G_DEFINE_TYPE (CcSubscriptionRegisterDialog, cc_subscription_register_dialog, GTK_TYPE_DIALOG);
9b746a
+
9b746a
+static void
9b746a
+dialog_reload (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  gboolean sensitive;
9b746a
+  gboolean url_entry_enabled;
9b746a
+
9b746a
+  switch (self->state)
9b746a
+    {
9b746a
+    case DIALOG_STATE_REGISTER:
9b746a
+      gtk_window_set_title (GTK_WINDOW (self), _("Register System"));
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->register_button), self->valid);
9b746a
+
9b746a
+      sensitive = TRUE;
9b746a
+      break;
9b746a
+
9b746a
+    case DIALOG_STATE_REGISTERING:
9b746a
+      gtk_window_set_title (GTK_WINDOW (self), _("Registering System…"));
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->register_button), FALSE);
9b746a
+
9b746a
+      sensitive = FALSE;
9b746a
+      break;
9b746a
+
9b746a
+    default:
9b746a
+      g_assert_not_reached ();
9b746a
+      break;
9b746a
+    }
9b746a
+
9b746a
+  url_entry_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->custom_url_radio));
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->url_entry), sensitive && url_entry_enabled);
9b746a
+
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->default_url_radio), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->custom_url_radio), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->register_radio), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->register_with_activation_keys_radio), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->login_entry), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->password_entry), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->activation_keys_entry), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->password_entry), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->organization_entry), sensitive);
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->organization_entry_with_activation_keys), sensitive);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+custom_url_radio_toggled_cb (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  gboolean active;
9b746a
+
9b746a
+  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->custom_url_radio));
9b746a
+  if (active)
9b746a
+    {
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->url_entry), TRUE);
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->url_label), TRUE);
9b746a
+
9b746a
+      gtk_entry_set_text (self->url_entry, "");
9b746a
+      gtk_widget_grab_focus (GTK_WIDGET (self->url_entry));
9b746a
+    }
9b746a
+  else
9b746a
+    {
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->url_entry), FALSE);
9b746a
+      gtk_widget_set_sensitive (GTK_WIDGET (self->url_label), FALSE);
9b746a
+
9b746a
+      gtk_entry_set_text (self->url_entry, SERVER_URL);
9b746a
+    }
9b746a
+
9b746a
+  dialog_validate (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+register_with_activation_keys_radio_toggled_cb (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  gint active;
9b746a
+
9b746a
+  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->register_with_activation_keys_radio));
9b746a
+  if (active)
9b746a
+    {
9b746a
+      gtk_stack_set_visible_child_name (self->stack, "register-with-activation-keys");
9b746a
+      gtk_widget_grab_focus (GTK_WIDGET (self->activation_keys_entry));
9b746a
+    }
9b746a
+  else
9b746a
+    {
9b746a
+      gtk_stack_set_visible_child_name (self->stack, "register");
9b746a
+      gtk_widget_grab_focus (GTK_WIDGET (self->login_entry));
9b746a
+    }
9b746a
+
9b746a
+  dialog_validate (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+dialog_validate (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  gboolean valid_url = TRUE;
9b746a
+  gboolean valid_login = TRUE;
9b746a
+  gboolean valid_password = TRUE;
9b746a
+  gboolean valid_activation_keys = TRUE;
9b746a
+  gboolean valid_organization = TRUE;
9b746a
+
9b746a
+  /* require url when custom url radio is selected */
9b746a
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->custom_url_radio)))
9b746a
+    {
9b746a
+      const gchar *url;
9b746a
+
9b746a
+      url = gtk_entry_get_text (self->url_entry);
9b746a
+      valid_url = url != NULL && strlen (url) != 0;
9b746a
+    }
9b746a
+
9b746a
+  /* activation keys radio selected */
9b746a
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->register_with_activation_keys_radio)))
9b746a
+    {
9b746a
+      const gchar *activation_keys;
9b746a
+      const gchar *organization;
9b746a
+
9b746a
+      /* require activation keys */
9b746a
+      activation_keys = gtk_entry_get_text (self->activation_keys_entry);
9b746a
+      valid_activation_keys = activation_keys != NULL && strlen (activation_keys) != 0;
9b746a
+
9b746a
+      /* organization is required when using activation keys */
9b746a
+      organization = gtk_entry_get_text (self->organization_entry_with_activation_keys);
9b746a
+      valid_organization = organization != NULL && strlen (organization) != 0;
9b746a
+
9b746a
+      /* username/password radio selected */
9b746a
+    }
9b746a
+  else
9b746a
+    {
9b746a
+      const gchar *login;
9b746a
+      const gchar *password;
9b746a
+
9b746a
+      /* require login */
9b746a
+      login = gtk_entry_get_text (self->login_entry);
9b746a
+      valid_login = login != NULL && strlen (login) != 0;
9b746a
+
9b746a
+      /* require password */
9b746a
+      password = gtk_entry_get_text (self->password_entry);
9b746a
+      valid_password = password != NULL && strlen (password) != 0;
9b746a
+    }
9b746a
+
9b746a
+  self->valid = valid_url && valid_login && valid_password && valid_activation_keys && valid_organization;
9b746a
+  gtk_widget_set_sensitive (GTK_WIDGET (self->register_button), self->valid);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+registration_done_cb (GObject      *source_object,
9b746a
+                      GAsyncResult *res,
9b746a
+                      gpointer      user_data)
9b746a
+{
9b746a
+  CcSubscriptionRegisterDialog *self = (CcSubscriptionRegisterDialog *) user_data;
9b746a
+  g_autoptr(GVariant) results = NULL;
9b746a
+  g_autoptr(GError) error = NULL;
9b746a
+
9b746a
+  results = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
9b746a
+                                      res,
9b746a
+                                      &error);
9b746a
+  if (results == NULL)
9b746a
+    {
9b746a
+      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
9b746a
+        return;
9b746a
+
9b746a
+      g_dbus_error_strip_remote_error (error);
9b746a
+      gtk_label_set_text (self->error_label, error->message);
9b746a
+      gtk_revealer_set_reveal_child (self->notification_revealer, TRUE);
9b746a
+
9b746a
+      gtk_spinner_stop (self->spinner);
9b746a
+
9b746a
+      self->state = DIALOG_STATE_REGISTER;
9b746a
+      dialog_reload (self);
9b746a
+      return;
9b746a
+    }
9b746a
+
9b746a
+  gtk_spinner_stop (self->spinner);
9b746a
+  gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_ACCEPT);
9b746a
+  return;
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+subscription_register_with_activation_keys (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  g_autoptr(GVariantBuilder) options_builder = NULL;
9b746a
+  const gchar *hostname;
9b746a
+  const gchar *organization;
9b746a
+  const gchar *activation_keys;
9b746a
+
9b746a
+  hostname = gtk_entry_get_text (self->url_entry);
9b746a
+  organization = gtk_entry_get_text (self->organization_entry_with_activation_keys);
9b746a
+  activation_keys = gtk_entry_get_text (self->activation_keys_entry);
9b746a
+
9b746a
+  options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "kind", g_variant_new_string ("key"));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "hostname", g_variant_new_string (hostname));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "organisation", g_variant_new_string (organization));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "activation-key", g_variant_new_string (activation_keys));
9b746a
+
9b746a
+  g_dbus_proxy_call (self->subscription_proxy,
9b746a
+                     "Register",
9b746a
+                     g_variant_new ("(a{sv})",
9b746a
+                                    options_builder),
9b746a
+                     G_DBUS_CALL_FLAGS_NONE,
9b746a
+                     DBUS_TIMEOUT,
9b746a
+                     self->cancellable,
9b746a
+                     registration_done_cb,
9b746a
+                     self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+subscription_register_with_username (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  g_autoptr(GVariantBuilder) options_builder = NULL;
9b746a
+  const gchar *hostname;
9b746a
+  const gchar *organization;
9b746a
+  const gchar *username;
9b746a
+  const gchar *password;
9b746a
+
9b746a
+  hostname = gtk_entry_get_text (self->url_entry);
9b746a
+  organization = gtk_entry_get_text (self->organization_entry);
9b746a
+  username = gtk_entry_get_text (self->login_entry);
9b746a
+  password = gtk_entry_get_text (self->password_entry);
9b746a
+
9b746a
+  options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "kind", g_variant_new_string ("username"));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "hostname", g_variant_new_string (hostname));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "organisation", g_variant_new_string (organization));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "username", g_variant_new_string (username));
9b746a
+  g_variant_builder_add (options_builder, "{sv}", "password", g_variant_new_string (password));
9b746a
+
9b746a
+  g_dbus_proxy_call (self->subscription_proxy,
9b746a
+                     "Register",
9b746a
+                     g_variant_new ("(a{sv})", options_builder),
9b746a
+                     G_DBUS_CALL_FLAGS_NONE,
9b746a
+                     DBUS_TIMEOUT,
9b746a
+                     self->cancellable,
9b746a
+                     registration_done_cb,
9b746a
+                     self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+register_button_clicked_cb (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->register_with_activation_keys_radio)))
9b746a
+    subscription_register_with_activation_keys (self);
9b746a
+  else
9b746a
+    subscription_register_with_username (self);
9b746a
+
9b746a
+  gtk_spinner_start (self->spinner);
9b746a
+
9b746a
+  self->state = DIALOG_STATE_REGISTERING;
9b746a
+  dialog_reload (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+dismiss_notification (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  gtk_revealer_set_reveal_child (self->notification_revealer, FALSE);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_register_dialog_init (CcSubscriptionRegisterDialog *self)
9b746a
+{
9b746a
+  gtk_widget_init_template (GTK_WIDGET (self));
9b746a
+
9b746a
+  self->cancellable = g_cancellable_new ();
9b746a
+  self->state = DIALOG_STATE_REGISTER;
9b746a
+
9b746a
+  gtk_entry_set_text (self->url_entry, SERVER_URL);
9b746a
+  gtk_widget_grab_focus (GTK_WIDGET (self->login_entry));
9b746a
+  dialog_validate (self);
9b746a
+  dialog_reload (self);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_register_dialog_dispose (GObject *obj)
9b746a
+{
9b746a
+  CcSubscriptionRegisterDialog *self = (CcSubscriptionRegisterDialog *) obj;
9b746a
+
9b746a
+  g_cancellable_cancel (self->cancellable);
9b746a
+  g_clear_object (&self->cancellable);
9b746a
+  g_clear_object (&self->subscription_proxy);
9b746a
+
9b746a
+  G_OBJECT_CLASS (cc_subscription_register_dialog_parent_class)->dispose (obj);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_register_dialog_finalize (GObject *obj)
9b746a
+{
9b746a
+  G_OBJECT_CLASS (cc_subscription_register_dialog_parent_class)->finalize (obj);
9b746a
+}
9b746a
+
9b746a
+static void
9b746a
+cc_subscription_register_dialog_class_init (CcSubscriptionRegisterDialogClass *klass)
9b746a
+{
9b746a
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
9b746a
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
9b746a
+
9b746a
+  object_class->dispose = cc_subscription_register_dialog_dispose;
9b746a
+  object_class->finalize = cc_subscription_register_dialog_finalize;
9b746a
+
9b746a
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/info/cc-subscription-register-dialog.ui");
9b746a
+
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, spinner);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_button);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, notification_revealer);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, error_label);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, default_url_radio);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, custom_url_radio);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_radio);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_with_activation_keys_radio);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, stack);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_grid);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, register_with_activation_keys_grid);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, url_label);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, url_entry);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, login_entry);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, password_entry);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, activation_keys_entry);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, organization_label);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, organization_entry);
9b746a
+  gtk_widget_class_bind_template_child (widget_class, CcSubscriptionRegisterDialog, organization_entry_with_activation_keys);
9b746a
+
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, dialog_validate);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, register_button_clicked_cb);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, dismiss_notification);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, custom_url_radio_toggled_cb);
9b746a
+  gtk_widget_class_bind_template_callback (widget_class, register_with_activation_keys_radio_toggled_cb);
9b746a
+}
9b746a
+
9b746a
+CcSubscriptionRegisterDialog *
9b746a
+cc_subscription_register_dialog_new (GDBusProxy *subscription_proxy)
9b746a
+{
9b746a
+  CcSubscriptionRegisterDialog *self;
9b746a
+
9b746a
+  self = g_object_new (CC_TYPE_SUBSCRIPTION_REGISTER_DIALOG, "use-header-bar", TRUE, NULL);
9b746a
+  self->subscription_proxy = g_object_ref (subscription_proxy);
9b746a
+
9b746a
+  return self;
9b746a
+}
9b746a
diff --git a/panels/info/cc-subscription-register-dialog.h b/panels/info/cc-subscription-register-dialog.h
9b746a
new file mode 100644
9b746a
index 000000000..c5918df9f
9b746a
--- /dev/null
9b746a
+++ b/panels/info/cc-subscription-register-dialog.h
9b746a
@@ -0,0 +1,32 @@
9b746a
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
9b746a
+ *
9b746a
+ * Copyright 2019  Red Hat, Inc,
9b746a
+ *
9b746a
+ * This program is free software; you can redistribute it and/or modify
9b746a
+ * it under the terms of the GNU General Public License as published by
9b746a
+ * the Free Software Foundation; either version 2 of the License, or
9b746a
+ * (at your option) any later version.
9b746a
+ *
9b746a
+ * This program is distributed in the hope that it will be useful,
9b746a
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9b746a
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9b746a
+ * GNU General Public License for more details.
9b746a
+ *
9b746a
+ * You should have received a copy of the GNU General Public License
9b746a
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
9b746a
+ *
9b746a
+ * Written by: Kalev Lember <klember@redhat.com>
9b746a
+ */
9b746a
+
9b746a
+#pragma once
9b746a
+
9b746a
+#include <gtk/gtk.h>
9b746a
+
9b746a
+G_BEGIN_DECLS
9b746a
+
9b746a
+#define CC_TYPE_SUBSCRIPTION_REGISTER_DIALOG (cc_subscription_register_dialog_get_type ())
9b746a
+G_DECLARE_FINAL_TYPE (CcSubscriptionRegisterDialog, cc_subscription_register_dialog, CC, SUBSCRIPTION_REGISTER_DIALOG, GtkDialog)
9b746a
+
9b746a
+CcSubscriptionRegisterDialog *cc_subscription_register_dialog_new (GDBusProxy *subscription_proxy);
9b746a
+
9b746a
+G_END_DECLS
9b746a
diff --git a/panels/info/cc-subscription-register-dialog.ui b/panels/info/cc-subscription-register-dialog.ui
9b746a
new file mode 100644
9b746a
index 000000000..21e317b41
9b746a
--- /dev/null
9b746a
+++ b/panels/info/cc-subscription-register-dialog.ui
9b746a
@@ -0,0 +1,623 @@
9b746a
+
9b746a
+<interface>
9b746a
+  <template class="CcSubscriptionRegisterDialog" parent="GtkDialog">
9b746a
+    <property name="can_focus">False</property>
9b746a
+    <property name="resizable">False</property>
9b746a
+    <property name="modal">True</property>
9b746a
+    <property name="destroy_with_parent">True</property>
9b746a
+    <property name="type_hint">dialog</property>
9b746a
+    <property name="title" translatable="yes">Register System</property>
9b746a
+    <property name="use_header_bar">1</property>
9b746a
+    <child internal-child="headerbar">
9b746a
+      <object class="GtkHeaderBar">
9b746a
+        <property name="visible">True</property>
9b746a
+        <property name="can_focus">False</property>
9b746a
+        <property name="show_close_button">False</property>
9b746a
+        <child>
9b746a
+          <object class="GtkButton" id="cancel_button">
9b746a
+            <property name="label" translatable="yes">_Cancel</property>
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="can_focus">True</property>
9b746a
+            <property name="can_default">True</property>
9b746a
+            <property name="receives_default">True</property>
9b746a
+            <property name="use_action_appearance">False</property>
9b746a
+            <property name="use_underline">True</property>
9b746a
+            <property name="valign">center</property>
9b746a
+            <style>
9b746a
+              <class name="text-button"/>
9b746a
+            </style>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="pack_type">start</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+        <child>
9b746a
+          <object class="GtkButton" id="register_button">
9b746a
+            <property name="label" translatable="yes">_Register</property>
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="can_focus">True</property>
9b746a
+            <property name="can_default">True</property>
9b746a
+            <property name="has_default">True</property>
9b746a
+            <property name="receives_default">True</property>
9b746a
+            <property name="use_action_appearance">False</property>
9b746a
+            <property name="use_underline">True</property>
9b746a
+            <property name="valign">center</property>
9b746a
+            <signal name="clicked" handler="register_button_clicked_cb" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+            <style>
9b746a
+              <class name="text-button"/>
9b746a
+              <class name="suggested-action"/>
9b746a
+            </style>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="pack_type">end</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+        <child>
9b746a
+          <object class="GtkSpinner" id="spinner">
9b746a
+            <property name="visible">True</property>
9b746a
+            <property name="can_focus">False</property>
9b746a
+            <property name="valign">center</property>
9b746a
+            <property name="margin_start">6</property>
9b746a
+            <property name="margin_end">6</property>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="pack_type">end</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+      </object>
9b746a
+    </child>
9b746a
+    <child internal-child="vbox">
9b746a
+      <object class="GtkBox">
9b746a
+        <property name="visible">True</property>
9b746a
+        <property name="can_focus">False</property>
9b746a
+        <property name="orientation">vertical</property>
9b746a
+        <property name="border_width">0</property>
9b746a
+        <child>
9b746a
+          <object class="GtkOverlay" id="overlay">
9b746a
+            <property name="visible">True</property>
9b746a
+            <child type="overlay">
9b746a
+              <object class="GtkRevealer" id="notification_revealer">
9b746a
+                <property name="visible">True</property>
9b746a
+                <property name="halign">fill</property>
9b746a
+                <property name="hexpand">True</property>
9b746a
+                <property name="margin_start">20</property>
9b746a
+                <property name="margin_end">20</property>
9b746a
+                <property name="valign">start</property>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="spacing">6</property>
9b746a
+                    <style>
9b746a
+                      <class name="app-notification"/>
9b746a
+                    </style>
9b746a
+                    <child>
9b746a
+                      <object class="GtkBox">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="orientation">vertical</property>
9b746a
+                        <property name="margin_start">6</property>
9b746a
+                        <property name="margin_end">6</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                        <property name="halign">start</property>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <property name="wrap">True</property>
9b746a
+                            <property name="label" translatable="yes">Failed to Register System</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="weight" value="bold"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="error_label">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <property name="wrap">True</property>
9b746a
+                            <property name="wrap_mode">word-char</property>
9b746a
+                            <property name="label">Unable to reach developers.redhat.com. Please try again later.</property>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkButton" id="dismiss_button">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="valign">start</property>
9b746a
+                        <signal name="clicked" handler="dismiss_notification" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                        <style>
9b746a
+                          <class name="flat"/>
9b746a
+                        </style>
9b746a
+                        <child>
9b746a
+                          <object class="GtkImage">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="icon_name">window-close-symbolic</property>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                </child>
9b746a
+              </object>
9b746a
+            </child>
9b746a
+            <child>
9b746a
+              <object class="GtkGrid">
9b746a
+                <property name="visible">True</property>
9b746a
+                <property name="hexpand">True</property>
9b746a
+                <property name="column_spacing">6</property>
9b746a
+                <property name="row_spacing">6</property>
9b746a
+                <property name="margin_top">24</property>
9b746a
+                <property name="margin_start">32</property>
9b746a
+                <property name="margin_end">32</property>
9b746a
+                <property name="margin_bottom">20</property>
9b746a
+                <child>
9b746a
+                  <object class="GtkLabel">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="can_focus">False</property>
9b746a
+                    <property name="label" translatable="yes">Register this system with Red Hat to receive software updates.</property>
9b746a
+                    <property name="width_chars">45</property>
9b746a
+                    <property name="max_width_chars">45</property>
9b746a
+                    <property name="xalign">0</property>
9b746a
+                    <property name="halign">start</property>
9b746a
+                    <property name="wrap">True</property>
9b746a
+                    <style>
9b746a
+                      <class name="dim-label"/>
9b746a
+                    </style>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">0</property>
9b746a
+                    <property name="width">2</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkLabel">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="can_focus">False</property>
9b746a
+                    <property name="label" translatable="yes">Registration Server</property>
9b746a
+                    <property name="margin_top">12</property>
9b746a
+                    <property name="halign">start</property>
9b746a
+                    <attributes>
9b746a
+                      <attribute name="weight" value="bold"/>
9b746a
+                    </attributes>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">1</property>
9b746a
+                    <property name="width">2</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="orientation">vertical</property>
9b746a
+                    <property name="margin_bottom">3</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkRadioButton" id="default_url_radio">
9b746a
+                        <property name="label" translatable="yes">Red Hat</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="receives_default">False</property>
9b746a
+                        <property name="active">True</property>
9b746a
+                        <property name="draw_indicator">True</property>
9b746a
+                      </object>
9b746a
+                      <packing>
9b746a
+                        <property name="position">0</property>
9b746a
+                      </packing>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkRadioButton" id="custom_url_radio">
9b746a
+                        <property name="label" translatable="yes">Custom Address</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="receives_default">False</property>
9b746a
+                        <property name="active">True</property>
9b746a
+                        <property name="draw_indicator">True</property>
9b746a
+                        <property name="group">default_url_radio</property>
9b746a
+                        <signal name="toggled" handler="custom_url_radio_toggled_cb" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                      </object>
9b746a
+                      <packing>
9b746a
+                        <property name="position">1</property>
9b746a
+                      </packing>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">2</property>
9b746a
+                    <property name="width">3</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkLabel" id="url_label">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="xalign">1</property>
9b746a
+                    <property name="label" translatable="yes">_URL</property>
9b746a
+                    <property name="sensitive">False</property>
9b746a
+                    <property name="use_underline">True</property>
9b746a
+                    <property name="mnemonic_widget">url_entry</property>
9b746a
+                    <style>
9b746a
+                      <class name="dim-label"/>
9b746a
+                    </style>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">3</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkEntry" id="url_entry">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="sensitive">False</property>
9b746a
+                    <property name="max-length">255</property>
9b746a
+                    <property name="can_focus">True</property>
9b746a
+                    <property name="activates_default">True</property>
9b746a
+                    <property name="hexpand">True</property>
9b746a
+                    <property name="has_focus">True</property>
9b746a
+                    <signal name="changed" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                    <signal name="activate" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">1</property>
9b746a
+                    <property name="top_attach">3</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkLabel">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="can_focus">False</property>
9b746a
+                    <property name="label" translatable="yes">Registration Type</property>
9b746a
+                    <property name="margin_top">12</property>
9b746a
+                    <property name="halign">start</property>
9b746a
+                    <attributes>
9b746a
+                      <attribute name="weight" value="bold"/>
9b746a
+                    </attributes>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">4</property>
9b746a
+                    <property name="width">2</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="orientation">vertical</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkRadioButton" id="register_radio">
9b746a
+                        <property name="label" translatable="yes">Red Hat Account</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="receives_default">False</property>
9b746a
+                        <property name="active">True</property>
9b746a
+                        <property name="draw_indicator">True</property>
9b746a
+                      </object>
9b746a
+                      <packing>
9b746a
+                        <property name="position">0</property>
9b746a
+                      </packing>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkRadioButton" id="register_with_activation_keys_radio">
9b746a
+                        <property name="label" translatable="yes">Activation Keys</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="receives_default">False</property>
9b746a
+                        <property name="active">True</property>
9b746a
+                        <property name="draw_indicator">True</property>
9b746a
+                        <property name="group">register_radio</property>
9b746a
+                        <signal name="toggled" handler="register_with_activation_keys_radio_toggled_cb" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                      </object>
9b746a
+                      <packing>
9b746a
+                        <property name="position">1</property>
9b746a
+                      </packing>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">5</property>
9b746a
+                    <property name="width">3</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkStack" id="stack">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="can_focus">False</property>
9b746a
+                    <property name="transition-type">none</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkGrid" id="register_grid">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                        <property name="column_spacing">6</property>
9b746a
+                        <property name="row_spacing">6</property>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="label" translatable="yes">Registration Details</property>
9b746a
+                            <property name="margin_top">12</property>
9b746a
+                            <property name="margin_bottom">6</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="weight" value="bold"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">0</property>
9b746a
+                            <property name="width">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="login_label">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="xalign">1</property>
9b746a
+                            <property name="label" translatable="yes">_Login</property>
9b746a
+                            <property name="use_underline">True</property>
9b746a
+                            <property name="mnemonic_widget">login_entry</property>
9b746a
+                            <style>
9b746a
+                              <class name="dim-label"/>
9b746a
+                            </style>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkEntry" id="login_entry">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="max-length">255</property>
9b746a
+                            <property name="can_focus">True</property>
9b746a
+                            <property name="activates_default">True</property>
9b746a
+                            <property name="hexpand">True</property>
9b746a
+                            <property name="has_focus">True</property>
9b746a
+                            <signal name="changed" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                            <signal name="activate" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">1</property>
9b746a
+                            <property name="top_attach">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="password_label">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="xalign">1</property>
9b746a
+                            <property name="label" translatable="yes">_Password</property>
9b746a
+                            <property name="use_underline">True</property>
9b746a
+                            <property name="mnemonic_widget">password_entry</property>
9b746a
+                            <style>
9b746a
+                              <class name="dim-label"/>
9b746a
+                            </style>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">3</property>
9b746a
+                            <property name="width">1</property>
9b746a
+                            <property name="height">1</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkEntry" id="password_entry">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">True</property>
9b746a
+                            <property name="has_tooltip">True</property>
9b746a
+                            <property name="visibility">False</property>
9b746a
+                            <property name="invisible_char">●</property>
9b746a
+                            <property name="invisible_char_set">True</property>
9b746a
+                            <property name="hexpand">True</property>
9b746a
+                            <property name="activates_default">True</property>
9b746a
+                            <property name="input_purpose">password</property>
9b746a
+                            <signal name="notify::text" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                            <signal name="activate" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">1</property>
9b746a
+                            <property name="top_attach">3</property>
9b746a
+                            <property name="width">1</property>
9b746a
+                            <property name="height">1</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="organization_label">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="xalign">1</property>
9b746a
+                            <property name="label" translatable="yes">_Organization</property>
9b746a
+                            <property name="use_underline">True</property>
9b746a
+                            <property name="mnemonic_widget">organization_entry</property>
9b746a
+                            <style>
9b746a
+                              <class name="dim-label"/>
9b746a
+                            </style>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">4</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkEntry" id="organization_entry">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="max-length">255</property>
9b746a
+                            <property name="can_focus">True</property>
9b746a
+                            <property name="activates_default">True</property>
9b746a
+                            <property name="hexpand">True</property>
9b746a
+                            <property name="has_focus">True</property>
9b746a
+                            <signal name="changed" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                            <signal name="activate" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">1</property>
9b746a
+                            <property name="top_attach">4</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                      <packing>
9b746a
+                        <property name="name">register</property>
9b746a
+                      </packing>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkGrid" id="register_with_activation_keys_grid">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                        <property name="column_spacing">6</property>
9b746a
+                        <property name="row_spacing">6</property>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="label" translatable="yes">Registration Details</property>
9b746a
+                            <property name="margin_top">12</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="weight" value="bold"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">0</property>
9b746a
+                            <property name="width">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="label" translatable="yes">Enter comma separated activation key(s). If the activation keys have conflicting settings, the rightmost key takes precedence.</property>
9b746a
+                            <property name="width_chars">45</property>
9b746a
+                            <property name="max_width_chars">45</property>
9b746a
+                            <property name="wrap">True</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="halign">start</property>
9b746a
+                            <property name="margin_bottom">6</property>
9b746a
+                            <style>
9b746a
+                              <class name="dim-label"/>
9b746a
+                            </style>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">1</property>
9b746a
+                            <property name="width">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="activation_keys_label">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="xalign">1</property>
9b746a
+                            <property name="label" translatable="yes">_Activation Keys</property>
9b746a
+                            <property name="use_underline">True</property>
9b746a
+                            <property name="mnemonic_widget">activation_keys_entry</property>
9b746a
+                            <style>
9b746a
+                              <class name="dim-label"/>
9b746a
+                            </style>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkEntry" id="activation_keys_entry">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="max-length">255</property>
9b746a
+                            <property name="can_focus">True</property>
9b746a
+                            <property name="activates_default">True</property>
9b746a
+                            <property name="hexpand">True</property>
9b746a
+                            <property name="has_focus">True</property>
9b746a
+                            <signal name="changed" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                            <signal name="activate" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">1</property>
9b746a
+                            <property name="top_attach">2</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel" id="organization_label_with_activation_keys">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="xalign">1</property>
9b746a
+                            <property name="label" translatable="yes">_Organization</property>
9b746a
+                            <property name="use_underline">True</property>
9b746a
+                            <property name="mnemonic_widget">organization_entry_with_activation_keys</property>
9b746a
+                            <style>
9b746a
+                              <class name="dim-label"/>
9b746a
+                            </style>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">0</property>
9b746a
+                            <property name="top_attach">3</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkEntry" id="organization_entry_with_activation_keys">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="max-length">255</property>
9b746a
+                            <property name="can_focus">True</property>
9b746a
+                            <property name="activates_default">True</property>
9b746a
+                            <property name="hexpand">True</property>
9b746a
+                            <property name="has_focus">True</property>
9b746a
+                            <signal name="changed" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                            <signal name="activate" handler="dialog_validate" object="CcSubscriptionRegisterDialog" swapped="yes"/>
9b746a
+                          </object>
9b746a
+                          <packing>
9b746a
+                            <property name="left_attach">1</property>
9b746a
+                            <property name="top_attach">3</property>
9b746a
+                          </packing>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                      <packing>
9b746a
+                        <property name="name">register-with-activation-keys</property>
9b746a
+                      </packing>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="left_attach">0</property>
9b746a
+                    <property name="top_attach">8</property>
9b746a
+                    <property name="width">2</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+              </object>
9b746a
+            </child>
9b746a
+          </object>
9b746a
+          <packing>
9b746a
+            <property name="expand">False</property>
9b746a
+            <property name="fill">True</property>
9b746a
+            <property name="position">0</property>
9b746a
+          </packing>
9b746a
+        </child>
9b746a
+      </object>
9b746a
+    </child>
9b746a
+    <action-widgets>
9b746a
+      <action-widget response="-6">cancel_button</action-widget>
9b746a
+    </action-widgets>
9b746a
+  </template>
9b746a
+  <object class="GtkSizeGroup">
9b746a
+    <widgets>
9b746a
+      <widget name="url_label"/>
9b746a
+      <widget name="login_label"/>
9b746a
+      <widget name="password_label"/>
9b746a
+      <widget name="activation_keys_label"/>
9b746a
+      <widget name="organization_label"/>
9b746a
+      <widget name="organization_label_with_activation_keys"/>
9b746a
+    </widgets>
9b746a
+  </object>
9b746a
+  <object class="GtkSizeGroup">
9b746a
+    <widgets>
9b746a
+      <widget name="url_entry"/>
9b746a
+      <widget name="login_entry"/>
9b746a
+      <widget name="password_entry"/>
9b746a
+      <widget name="activation_keys_entry"/>
9b746a
+      <widget name="password_entry"/>
9b746a
+      <widget name="organization_entry"/>
9b746a
+      <widget name="organization_entry_with_activation_keys"/>
9b746a
+    </widgets>
9b746a
+  </object>
9b746a
+  <object class="GtkSizeGroup">
9b746a
+    <property name="mode">horizontal</property>
9b746a
+    <widgets>
9b746a
+      <widget name="register_button"/>
9b746a
+      <widget name="cancel_button"/>
9b746a
+    </widgets>
9b746a
+  </object>
9b746a
+</interface>
9b746a
diff --git a/panels/info/info-overview.ui b/panels/info/info-overview.ui
9b746a
index aa87fbec2..e33ba399a 100644
9b746a
--- a/panels/info/info-overview.ui
9b746a
+++ b/panels/info/info-overview.ui
06e1d8
@@ -1,46 +1,47 @@
06e1d8
 
06e1d8
 <interface>
06e1d8
   
9b746a
   <template class="CcInfoOverviewPanel" parent="CcPanel">
9b746a
     <property name="visible">True</property>
9b746a
     <property name="can-focus">False</property>
9b746a
-    <property name="valign">center</property>
9b746a
-    <property name="halign">center</property>
9b746a
     <property name="expand">True</property>
9b746a
-    <property name="margin">24</property>
9b746a
     <child>
9b746a
       <object class="GtkBox">
9b746a
         <property name="visible">True</property>
9b746a
         <property name="can_focus">False</property>
9b746a
         <property name="spacing">6</property>
9b746a
         <property name="orientation">vertical</property>
9b746a
+        <property name="margin_top">63</property>
9b746a
+        <property name="margin_start">12</property>
9b746a
+        <property name="margin_end">12</property>
9b746a
+        <property name="margin_bottom">12</property>
9b746a
         <child>
9b746a
           <object class="GtkImage" id="system_image">
9b746a
             <property name="visible">True</property>
06e1d8
             <property name="can_focus">False</property>
06e1d8
             <property name="pixel_size">128</property>
06e1d8
             <property name="icon_name">fedora-logo-icon</property>
06e1d8
           </object>
06e1d8
           <packing>
06e1d8
             <property name="expand">False</property>
06e1d8
             <property name="fill">False</property>
06e1d8
             <property name="position">0</property>
06e1d8
           </packing>
06e1d8
         </child>
06e1d8
         <child>
06e1d8
           <object class="GtkLabel" id="os_name_label">
06e1d8
             <property name="visible">True</property>
06e1d8
             <property name="can_focus">False</property>
06e1d8
             <property name="label">Version 3.0</property>
06e1d8
             <property name="selectable">True</property>
06e1d8
             <property name="margin-bottom">24</property>
06e1d8
             <attributes>
06e1d8
               <attribute name="scale" value="1.25"/>
06e1d8
             </attributes>
06e1d8
           </object>
06e1d8
           <packing>
06e1d8
             <property name="expand">False</property>
06e1d8
             <property name="fill">False</property>
06e1d8
             <property name="position">1</property>
06e1d8
           </packing>
06e1d8
         </child>
06e1d8
@@ -276,64 +277,181 @@
06e1d8
                 <property name="label" translatable="yes">Calculating…</property>
06e1d8
                 <property name="selectable">True</property>
06e1d8
               </object>
06e1d8
               <packing>
06e1d8
                 <property name="top-attach">7</property>
06e1d8
                 <property name="left-attach">2</property>
06e1d8
               </packing>
06e1d8
             </child>
06e1d8
             <child>
06e1d8
               <object class="GtkLabel" id="dummy1">
06e1d8
                 <property name="visible">True</property>
06e1d8
                 <property name="can_focus">False</property>
06e1d8
                 <property name="label">    </property>
06e1d8
               </object>
06e1d8
               <packing>
06e1d8
                 <property name="top-attach">1</property>
06e1d8
                 <property name="left-attach">3</property>
06e1d8
               </packing>
06e1d8
             </child>
06e1d8
             <child>
06e1d8
               <placeholder/>
06e1d8
             </child>
06e1d8
           </object>
06e1d8
           <packing>
06e1d8
             <property name="expand">False</property>
06e1d8
             <property name="fill">False</property>
06e1d8
             <property name="position">2</property>
9b746a
           </packing>
9b746a
         </child>
9b746a
         <child>
9b746a
-          <object class="GtkButtonBox" id="hbuttonbox1">
9b746a
+          <object class="GtkBox">
9b746a
             <property name="visible">True</property>
9b746a
             <property name="can_focus">False</property>
9b746a
-            <property name="layout_style">end</property>
9b746a
             <property name="orientation">horizontal</property>
9b746a
+            <property name="margin_top">12</property>
9b746a
+            <property name="spacing">12</property>
9b746a
             <child>
9b746a
-              <placeholder/>
9b746a
+              <object class="GtkStack" id="subscription_stack">
9b746a
+                <property name="visible">True</property>
9b746a
+                <property name="can_focus">False</property>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="can_focus">False</property>
9b746a
+                    <property name="orientation">horizontal</property>
9b746a
+                    <property name="spacing">12</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkBox">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">False</property>
9b746a
+                        <property name="orientation">vertical</property>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="label" translatable="yes">System Not Registered</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="scale" value="0.95"/>
9b746a
+                              <attribute name="weight" value="bold"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="label" translatable="yes">Register this system to receive software updates.</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="scale" value="0.8"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkButton" id="register_button">
9b746a
+                        <property name="label" translatable="yes">_Register…</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="use_underline">True</property>
9b746a
+                        <property name="use_action_appearance">False</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                        <property name="halign">end</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <style>
9b746a
+                          <class name="suggested-action"/>
9b746a
+                        </style>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="name">not-registered</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+                <child>
9b746a
+                  <object class="GtkBox">
9b746a
+                    <property name="visible">True</property>
9b746a
+                    <property name="can_focus">False</property>
9b746a
+                    <property name="orientation">horizontal</property>
9b746a
+                    <property name="spacing">12</property>
9b746a
+                    <child>
9b746a
+                      <object class="GtkBox">
9b746a
+                        <property name="visible">True</property>
9b746a
+                        <property name="can_focus">False</property>
9b746a
+                        <property name="orientation">vertical</property>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="label" translatable="yes">Registered System</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="scale" value="0.95"/>
9b746a
+                              <attribute name="weight" value="bold"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                        <child>
9b746a
+                          <object class="GtkLabel">
9b746a
+                            <property name="visible">True</property>
9b746a
+                            <property name="can_focus">False</property>
9b746a
+                            <property name="xalign">0</property>
9b746a
+                            <property name="label" translatable="yes">System is registered and able to receive software updates.</property>
9b746a
+                            <attributes>
9b746a
+                              <attribute name="scale" value="0.8"/>
9b746a
+                            </attributes>
9b746a
+                          </object>
9b746a
+                        </child>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                    <child>
9b746a
+                      <object class="GtkButton" id="details_button">
9b746a
+                        <property name="label" translatable="yes">_Details</property>
9b746a
+                        <property name="can_focus">True</property>
9b746a
+                        <property name="use_underline">True</property>
9b746a
+                        <property name="receives_default">True</property>
9b746a
+                        <property name="use_action_appearance">False</property>
9b746a
+                        <property name="hexpand">True</property>
9b746a
+                        <property name="halign">end</property>
9b746a
+                        <property name="visible">True</property>
9b746a
+                      </object>
9b746a
+                    </child>
9b746a
+                  </object>
9b746a
+                  <packing>
9b746a
+                    <property name="name">registered</property>
9b746a
+                  </packing>
9b746a
+                </child>
9b746a
+              </object>
9b746a
+            </child>
9b746a
+            <child>
9b746a
+              <object class="GtkSeparator" id="updates_separator">
9b746a
+                <property name="visible">True</property>
9b746a
+              </object>
9b746a
             </child>
9b746a
             <child>
9b746a
               <object class="GtkButton" id="updates_button">
9b746a
-                <property name="label" translatable="yes">Check for updates</property>
9b746a
+                <property name="label" translatable="yes">_View Updates</property>
9b746a
                 <property name="can_focus">True</property>
9b746a
+                <property name="use_underline">True</property>
9b746a
                 <property name="receives_default">True</property>
9b746a
                 <property name="use_action_appearance">False</property>
9b746a
+                <property name="halign">end</property>
9b746a
                 <property name="visible">True</property>
9b746a
               </object>
9b746a
               <packing>
9b746a
-                <property name="expand">False</property>
9b746a
-                <property name="fill">True</property>
9b746a
-                <property name="position">1</property>
9b746a
+                <property name="pack_type">end</property>
9b746a
               </packing>
9b746a
             </child>
9b746a
           </object>
06e1d8
           <packing>
06e1d8
             <property name="expand">False</property>
06e1d8
             <property name="fill">False</property>
06e1d8
             <property name="pack_type">end</property>
06e1d8
             <property name="position">3</property>
06e1d8
           </packing>
06e1d8
         </child>
06e1d8
       </object>
06e1d8
     </child>
06e1d8
   </template>
06e1d8
 </interface>
9b746a
diff --git a/panels/info/info.gresource.xml b/panels/info/info.gresource.xml
9b746a
index c96722350..15d18daac 100644
9b746a
--- a/panels/info/info.gresource.xml
9b746a
+++ b/panels/info/info.gresource.xml
06e1d8
@@ -1,9 +1,11 @@
06e1d8
 
06e1d8
 <gresources>
06e1d8
   <gresource prefix="/org/gnome/control-center/info">
9b746a
     <file preprocess="xml-stripblanks">info-overview.ui</file>
9b746a
     <file preprocess="xml-stripblanks">info-default-apps.ui</file>
9b746a
     <file preprocess="xml-stripblanks">info-removable-media.ui</file>
9b746a
+    <file preprocess="xml-stripblanks">cc-subscription-details-dialog.ui</file>
9b746a
+    <file preprocess="xml-stripblanks">cc-subscription-register-dialog.ui</file>
9b746a
     <file>GnomeLogoVerticalMedium.svg</file>
9b746a
   </gresource>
9b746a
 </gresources>
9b746a
diff --git a/panels/info/meson.build b/panels/info/meson.build
9b746a
index 13015b96c..a4ff83a42 100644
9b746a
--- a/panels/info/meson.build
9b746a
+++ b/panels/info/meson.build
06e1d8
@@ -14,65 +14,69 @@ foreach name: panel_names
06e1d8
     output: desktop + '.in',
06e1d8
     configuration: desktop_conf
06e1d8
   )
06e1d8
 
06e1d8
   i18n.merge_file(
06e1d8
     desktop,
06e1d8
     type: 'desktop',
06e1d8
     input: desktop_in,
06e1d8
     output: desktop,
06e1d8
     po_dir: po_dir,
06e1d8
     install: true,
06e1d8
     install_dir: control_center_desktopdir
06e1d8
   )
06e1d8
 endforeach
06e1d8
 
06e1d8
 cflags += [
06e1d8
   '-DBINDIR="@0@"'.format(control_center_bindir),
06e1d8
   '-DDATADIR="@0@"'.format(control_center_datadir),
06e1d8
   '-DGNOME_SESSION_DIR="@0@"'.format(gnome_session_libexecdir),
06e1d8
   '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir)
06e1d8
 ]
06e1d8
 
06e1d8
 gsd_headers = ['gsd-disk-space-helper.h']
06e1d8
 
06e1d8
 gsd_sources = ['gsd-disk-space-helper.c']
06e1d8
 
06e1d8
 sources = files(gsd_sources) + files(
9b746a
   'cc-info-default-apps-panel.c',
9b746a
   'cc-info-overview-panel.c',
9b746a
   'cc-info-removable-media-panel.c',
9b746a
+  'cc-subscription-details-dialog.c',
9b746a
+  'cc-subscription-register-dialog.c',
9b746a
   'info-cleanup.c'
9b746a
 )
9b746a
 
9b746a
 resource_data = files(
9b746a
   'GnomeLogoVerticalMedium.svg',
9b746a
+  'cc-subscription-details-dialog.ui',
9b746a
+  'cc-subscription-register-dialog.ui',
9b746a
   'info-default-apps.ui',
9b746a
   'info-overview.ui',
9b746a
   'info-removable-media.ui'
06e1d8
 )
06e1d8
 
06e1d8
 sources += gnome.compile_resources(
06e1d8
   'cc-' + cappletname + '-resources',
06e1d8
   cappletname + '.gresource.xml',
06e1d8
   c_name: 'cc_' + cappletname,
06e1d8
   dependencies: resource_data,
06e1d8
   export: true
06e1d8
 )
06e1d8
 
06e1d8
 deps = common_deps + [
06e1d8
   polkit_gobject_dep,
06e1d8
   dependency('libgtop-2.0')
06e1d8
 ]
06e1d8
 
06e1d8
 panels_libs += static_library(
06e1d8
   cappletname,
06e1d8
   sources: sources,
06e1d8
   include_directories: top_inc,
06e1d8
   dependencies: deps,
06e1d8
   c_args: cflags
06e1d8
 )
06e1d8
 
06e1d8
 test_name = 'test-info-cleanup'
06e1d8
 
06e1d8
 sources = files(
06e1d8
   'info-cleanup.c',
9b746a
diff --git a/po/POTFILES.in b/po/POTFILES.in
9b746a
index dfd8ccff0..6cb8938e9 100644
9b746a
--- a/po/POTFILES.in
9b746a
+++ b/po/POTFILES.in
06e1d8
@@ -7,60 +7,64 @@ panels/background/cc-background-item.c
06e1d8
 panels/background/cc-background-panel.c
06e1d8
 panels/background/gnome-background-panel.desktop.in.in
06e1d8
 panels/bluetooth/bluetooth.ui
06e1d8
 panels/bluetooth/cc-bluetooth-panel.c
06e1d8
 panels/bluetooth/gnome-bluetooth-panel.desktop.in.in
06e1d8
 panels/color/cc-color-calibrate.c
06e1d8
 panels/color/cc-color-common.c
06e1d8
 panels/color/cc-color-device.c
06e1d8
 panels/color/cc-color-panel.c
06e1d8
 panels/color/cc-color-profile.c
06e1d8
 panels/color/color-calibrate.ui
06e1d8
 panels/color/color.ui
06e1d8
 panels/color/gnome-color-panel.desktop.in.in
06e1d8
 panels/common/cc-common-language.c
06e1d8
 panels/common/cc-language-chooser.c
06e1d8
 panels/common/cc-util.c
06e1d8
 panels/common/language-chooser.ui
06e1d8
 panels/datetime/big.ui
06e1d8
 panels/datetime/cc-datetime-panel.c
06e1d8
 panels/datetime/datetime.ui
06e1d8
 panels/datetime/gnome-datetime-panel.desktop.in.in
06e1d8
 panels/datetime/little.ui
06e1d8
 panels/datetime/middle.ui
06e1d8
 panels/datetime/org.gnome.controlcenter.datetime.policy.in
06e1d8
 panels/datetime/ydm.ui
06e1d8
 panels/display/cc-display-panel.c
06e1d8
 panels/display/display.ui
9b746a
 panels/display/gnome-display-panel.desktop.in.in
9b746a
 panels/info/cc-info-overview-panel.c
9b746a
 panels/info/cc-info-removable-media-panel.c
9b746a
+panels/info/cc-subscription-details-dialog.c
9b746a
+panels/info/cc-subscription-details-dialog.ui
9b746a
+panels/info/cc-subscription-register-dialog.c
9b746a
+panels/info/cc-subscription-register-dialog.ui
9b746a
 panels/info/gnome-default-apps-panel.desktop.in.in
9b746a
 panels/info/gnome-info-overview-panel.desktop.in.in
9b746a
 panels/info/gnome-removable-media-panel.desktop.in.in
06e1d8
 panels/info/info-default-apps.ui
06e1d8
 panels/info/info-overview.ui
06e1d8
 panels/info/info-removable-media.ui
06e1d8
 panels/keyboard/00-multimedia.xml.in
06e1d8
 panels/keyboard/01-input-sources.xml.in
06e1d8
 panels/keyboard/01-launchers.xml.in
06e1d8
 panels/keyboard/01-screenshot.xml.in
06e1d8
 panels/keyboard/01-system.xml.in
06e1d8
 panels/keyboard/50-accessibility.xml.in
06e1d8
 panels/keyboard/cc-keyboard-manager.c
06e1d8
 panels/keyboard/cc-keyboard-option.c
06e1d8
 panels/keyboard/cc-keyboard-panel.c
06e1d8
 panels/keyboard/cc-keyboard-shortcut-editor.c
06e1d8
 panels/keyboard/gnome-keyboard-panel.desktop.in.in
06e1d8
 panels/keyboard/gnome-keyboard-panel.ui
06e1d8
 panels/keyboard/keyboard-shortcuts.c
06e1d8
 panels/keyboard/shortcut-editor.ui
06e1d8
 panels/mouse/cc-mouse-panel.c
06e1d8
 panels/mouse/gnome-mouse-panel.desktop.in.in
06e1d8
 panels/mouse/gnome-mouse-properties.c
06e1d8
 panels/mouse/gnome-mouse-properties.ui
06e1d8
 panels/mouse/gnome-mouse-test.c
06e1d8
 panels/mouse/gnome-mouse-test.ui
06e1d8
 panels/network/cc-network-panel.c
06e1d8
 panels/network/cc-wifi-panel.c
06e1d8
 panels/network/connection-editor/8021x-security-page.ui
06e1d8
 panels/network/connection-editor/ce-page-8021x-security.c
9b746a
-- 
06e1d8
2.28.0
9b746a