~ubuntu-core-dev/update-notifier/ubuntu

« back to all changes in this revision

Viewing changes to src/reboot.c

  • Committer: Jeremy Bicha
  • Date: 2019-02-09 14:25:07 UTC
  • Revision ID: jbicha@ubuntu.com-20190209142507-45fc0sqnn4uqdl7j
Try adding gnome-shell as alternate dependency of notification-daemon

as part of an effort to drop notification-daemon to universe

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#ifdef HAVE_CONFIG_H
2
 
#include "config.h"
3
 
#endif
4
 
 
5
 
#include <sys/types.h>
6
 
#include <sys/stat.h>
7
 
#include <unistd.h>
8
 
 
9
 
#include <libnotify/notify.h>
10
 
#include <dbus/dbus-glib.h>
11
 
 
12
 
#include "update-notifier.h"
13
 
#include "update.h"
14
 
 
15
 
static GtkBuilder *builder;
16
 
 
17
 
static gboolean
18
 
show_notification (TrayApplet *ta)
19
 
{
20
 
        NotifyNotification *n;
21
 
 
22
 
        GdkRectangle area;
23
 
        gtk_status_icon_get_geometry(ta->tray_icon, NULL, &area, NULL);
24
 
 
25
 
        // no usefull coordiante yet, do another timeout
26
 
        if(area.x <= 0 || area.y <= 0 || area.width <= 0 || area.height <= 0)
27
 
           return TRUE;
28
 
 
29
 
        // only show once the icon is realy availabe
30
 
        if(!gtk_status_icon_get_visible(ta->tray_icon))
31
 
           return TRUE;
32
 
 
33
 
        /* Create and show the notification */
34
 
        n = notify_notification_new_with_status_icon(
35
 
                                     _("System restart required"),
36
 
                                     _("To complete the update of your system, "
37
 
                                       "please restart it.\n\n"
38
 
                                       "Click on the notification icon for "
39
 
                                       "details."),
40
 
                                     GTK_STOCK_DIALOG_WARNING,
41
 
                                     ta->tray_icon);
42
 
        notify_notification_set_timeout (n, 60000);
43
 
        notify_notification_show (n, NULL);
44
 
        g_object_set_data (G_OBJECT(ta->tray_icon), "notification", n);
45
 
 
46
 
        return FALSE;
47
 
}
48
 
 
49
 
static gboolean
50
 
gdm_action_reboot()
51
 
{
52
 
   DBusGConnection *connection;
53
 
   GError *error;
54
 
   DBusGProxy *proxy;
55
 
 
56
 
   error = NULL;
57
 
   connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
58
 
   if (connection == NULL) {
59
 
      g_error_free (error);
60
 
      return FALSE;
61
 
   }
62
 
 
63
 
  proxy = dbus_g_proxy_new_for_name (connection,
64
 
                                     "org.gnome.SessionManager",
65
 
                                     "/org/gnome/SessionManager",
66
 
                                     "org.gnome.SessionManager");
67
 
  if (proxy == NULL)
68
 
     return FALSE;
69
 
 
70
 
  error = NULL;
71
 
  if (!dbus_g_proxy_call (proxy, "RequestReboot", &error, 
72
 
                          G_TYPE_INVALID, G_TYPE_INVALID)) {
73
 
     g_error_free (error);
74
 
     return FALSE;
75
 
  }
76
 
  return TRUE;
77
 
}
78
 
 
79
 
static gboolean
80
 
hal_action_reboot()
81
 
{
82
 
   DBusGConnection *connection;
83
 
   GError *error;
84
 
   DBusGProxy *proxy;
85
 
 
86
 
   error = NULL;
87
 
   connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
88
 
   if (connection == NULL) {
89
 
      g_error_free (error);
90
 
      return FALSE;
91
 
   }
92
 
 
93
 
  proxy = dbus_g_proxy_new_for_name (connection,
94
 
                                     "org.freedesktop.Hal",
95
 
                                     "/org/freedesktop/Hal/devices/computer",
96
 
                                     "org.freedesktop.Hal.Device.SystemPowerManagement");
97
 
  if (proxy == NULL)
98
 
     return FALSE;
99
 
 
100
 
  error = NULL;
101
 
  if (!dbus_g_proxy_call (proxy, "Reboot", &error,
102
 
                          G_TYPE_INVALID, G_TYPE_INVALID)) {
103
 
     g_error_free (error);
104
 
     return FALSE;
105
 
  }
106
 
  return TRUE;
107
 
 
108
 
}
109
 
 
110
 
static void
111
 
request_reboot (void)
112
 
{
113
 
   if(!gdm_action_reboot() && !hal_action_reboot()) {
114
 
      const char *fmt, *msg, *details;
115
 
      fmt = "<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s\n";
116
 
      msg = _("Reboot failed");
117
 
      details = _("Failed to request reboot, please shutdown manually");
118
 
      GtkWidget *dlg = gtk_message_dialog_new_with_markup(NULL, 0,
119
 
                                                          GTK_MESSAGE_ERROR,
120
 
                                                          GTK_BUTTONS_CLOSE,
121
 
                                                          fmt, msg, details);
122
 
      gtk_dialog_run(GTK_DIALOG(dlg));
123
 
      gtk_widget_destroy(dlg);
124
 
   }
125
 
}
126
 
 
127
 
 
128
 
static void
129
 
ask_reboot_required(TrayApplet *ta, gboolean focus_on_map)
130
 
{
131
 
   GtkWidget *dia;
132
 
   
133
 
   dia = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_reboot"));
134
 
   gtk_window_set_focus_on_map(GTK_WINDOW(dia), focus_on_map);
135
 
   if (gtk_dialog_run (GTK_DIALOG(dia)) == GTK_RESPONSE_OK)
136
 
      request_reboot ();
137
 
   gtk_widget_hide (dia);
138
 
}
139
 
 
140
 
static gboolean
141
 
aptdaemon_pending_transactions ()
142
 
{
143
 
   DBusGConnection *connection;
144
 
   GError *error;
145
 
   DBusGProxy *proxy;
146
 
   char *current = NULL;
147
 
   char **pending = NULL;
148
 
  
149
 
   error = NULL;
150
 
   connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
151
 
   if (connection == NULL) {
152
 
      g_debug ("Failed to open connection to bus: %s\n", error->message);
153
 
      g_error_free (error);
154
 
      return FALSE;
155
 
   }
156
 
 
157
 
  proxy = dbus_g_proxy_new_for_name (connection,
158
 
                                     "org.debian.apt",
159
 
                                     "/org/debian/apt",
160
 
                                     "org.debian.apt");
161
 
  error = NULL;
162
 
  if (!dbus_g_proxy_call (proxy, "GetActiveTransactions", &error, 
163
 
                          G_TYPE_INVALID,
164
 
                          G_TYPE_STRING, &current, 
165
 
                          G_TYPE_STRV, &pending,
166
 
                          G_TYPE_INVALID)) {
167
 
     g_debug ("error during dbus call: %s\n", error->message);
168
 
     g_error_free (error);
169
 
     g_object_unref (proxy);
170
 
     return FALSE;
171
 
  }
172
 
 
173
 
  gboolean has_pending = FALSE;
174
 
  if ((current && strcmp(current,"") != 0) || g_strv_length(pending) > 0)
175
 
     has_pending = TRUE;
176
 
 
177
 
  g_object_unref (proxy);
178
 
  g_free (current);
179
 
  g_strfreev (pending);
180
 
 
181
 
  return has_pending;
182
 
}
183
 
 
184
 
static void
185
 
do_reboot_check (TrayApplet *ta)
186
 
{
187
 
        struct stat statbuf;
188
 
 
189
 
        // if we are not supposed to show the reboot notification
190
 
        // just skip it 
191
 
        if(gconf_client_get_bool((GConfClient*) ta->user_data,
192
 
                                 GCONF_KEY_HIDE_REBOOT, NULL))
193
 
           return;
194
 
        // no auto-open of this dialog 
195
 
        if(gconf_client_get_bool((GConfClient*) ta->user_data,
196
 
                                 GCONF_KEY_AUTO_LAUNCH, NULL)) {
197
 
           g_debug ("Skipping reboot required");
198
 
           return;
199
 
        }
200
 
 
201
 
        /* If the file doesn't exist, we don't need to reboot */
202
 
        if (stat (REBOOT_FILE, &statbuf)) {
203
 
                NotifyNotification *n;
204
 
 
205
 
                gtk_status_icon_set_visible (ta->tray_icon, FALSE);
206
 
                /* Hide any notification popup */
207
 
                n = g_object_get_data (G_OBJECT(ta->tray_icon), "notification");
208
 
                if (n)
209
 
                        notify_notification_close (n, NULL);
210
 
                g_object_set_data (G_OBJECT(ta->tray_icon), "notification", NULL);
211
 
 
212
 
                return;
213
 
        }
214
 
 
215
 
        /* Skip the rest if the icon is already visible */
216
 
        if (gtk_status_icon_get_visible (ta->tray_icon))
217
 
           return;
218
 
        gtk_status_icon_set_tooltip (ta->tray_icon,  
219
 
                                     _("System restart required"));
220
 
        gtk_status_icon_set_visible (ta->tray_icon, TRUE);
221
 
 
222
 
        /* Check whether the user doesn't like notifications */
223
 
        if (gconf_client_get_bool ((GConfClient*) ta->user_data,
224
 
                                   GCONF_KEY_NO_UPDATE_NOTIFICATIONS, NULL))
225
 
                return;
226
 
 
227
 
        /* Show the notification, after a delay so it doesn't look ugly
228
 
         * if we've just logged in */
229
 
        g_timeout_add(5000, (GSourceFunc)(show_notification), ta);
230
 
 
231
 
}
232
 
 
233
 
gboolean
234
 
reboot_check (TrayApplet *ta)
235
 
{
236
 
   if (aptdaemon_pending_transactions())
237
 
      g_timeout_add_seconds (5, (GSourceFunc)reboot_check, ta);
238
 
   else
239
 
      do_reboot_check(ta);
240
 
   return FALSE;
241
 
}
242
 
 
243
 
static gboolean
244
 
button_release_cb (GtkWidget *widget,
245
 
                   TrayApplet *ta)
246
 
{
247
 
   ask_reboot_required(ta, TRUE);
248
 
 
249
 
   return TRUE;
250
 
}
251
 
 
252
 
 
253
 
void
254
 
reboot_tray_icon_init (TrayApplet *ta)
255
 
{
256
 
        GtkWidget *widget;
257
 
        GError* error = NULL;
258
 
 
259
 
        builder = gtk_builder_new ();
260
 
        if (!gtk_builder_add_from_file (builder, UIDIR"reboot-dialog.ui", &error)) {
261
 
                g_warning ("Couldn't load builder file: %s", error->message);
262
 
                g_error_free (error);
263
 
        }
264
 
 
265
 
        widget = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
266
 
        GtkIconTheme* icon_theme = gtk_icon_theme_get_default();
267
 
        GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (icon_theme, "un-reboot",
268
 
                                                      48, 0,NULL);
269
 
        gtk_status_icon_set_from_pixbuf (ta->tray_icon, pixbuf);
270
 
        ta->user_data = gconf_client_get_default();
271
 
 
272
 
        g_signal_connect (G_OBJECT(ta->tray_icon),
273
 
                          "activate",
274
 
                          G_CALLBACK (button_release_cb),
275
 
                          ta);
276
 
 
277
 
        gtk_image_set_from_pixbuf(GTK_IMAGE(widget), pixbuf);
278
 
 
279
 
        /* Check for updates for the first time */
280
 
        reboot_check (ta);
281
 
}