1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
#include <glib/gi18n.h>
28
#include <packagekit-glib2/packagekit.h>
29
#include <libnotify/notify.h>
30
#include <gdesktop-enums.h>
32
#include "gsd-enums.h"
33
#include "gsd-updates-manager.h"
34
#include "gsd-updates-firmware.h"
35
#include "gsd-updates-refresh.h"
36
#include "gsd-updates-common.h"
37
#include "gnome-settings-profile.h"
38
#include "gnome-settings-bus.h"
40
#define GSD_UPDATES_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_UPDATES_MANAGER, GsdUpdatesManagerPrivate))
42
#define MAX_FAILED_GET_UPDATES 10 /* the maximum number of tries */
43
#define GSD_UPDATES_ICON_NORMAL "software-update-available-symbolic"
44
#define GSD_UPDATES_ICON_URGENT "software-update-urgent-symbolic"
45
#define GSD_UPDATES_CHECK_OFFLINE_TIMEOUT 30 /* time in seconds */
47
struct GsdUpdatesManagerPrivate
49
GCancellable *cancellable;
50
GsdUpdatesRefresh *refresh;
51
GsdUpdatesFirmware *firmware;
52
GSettings *settings_proxy;
53
GSettings *settings_ftp;
54
GSettings *settings_gsd;
55
GSettings *settings_http;
56
guint number_updates_critical_last_shown;
57
guint offline_update_id;
58
PkError *offline_update_error;
59
NotifyNotification *notification_updates;
63
GsdSessionManager *proxy_session;
64
guint update_viewer_watcher_id;
65
GVolumeMonitor *volume_monitor;
66
guint failed_get_updates_count;
67
GPtrArray *update_packages;
70
static void gsd_updates_manager_class_init (GsdUpdatesManagerClass *klass);
71
static void gsd_updates_manager_init (GsdUpdatesManager *updates_manager);
73
G_DEFINE_TYPE (GsdUpdatesManager, gsd_updates_manager, G_TYPE_OBJECT)
75
static gpointer manager_object = NULL;
78
child_exit_cb (GPid pid, gint status, gpointer user_data)
80
g_spawn_close_pid (pid);
84
clear_offline_updates_message (void)
92
argv[1] = LIBEXECDIR "/pk-clear-offline-update";
94
ret = g_spawn_async (NULL,
97
G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
103
g_warning ("Failure clearing offline update message: %s",
105
g_error_free (error);
108
g_child_watch_add (pid, child_exit_cb, NULL);
112
show_offline_updates_error (GsdUpdatesManager *manager)
115
gboolean show_geeky = FALSE;
119
/* TRANSLATORS: this is when the offline update failed */
120
title = _("Failed To Update");
121
msg = g_string_new ("");
122
switch (pk_error_get_code (manager->priv->offline_update_error)) {
123
case PK_ERROR_ENUM_UNFINISHED_TRANSACTION:
124
/* TRANSLATORS: the transaction could not be completed
125
* as a previous transaction was unfinished */
126
g_string_append (msg, _("A previous update was unfinished."));
129
case PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED:
130
case PK_ERROR_ENUM_NO_CACHE:
131
case PK_ERROR_ENUM_NO_NETWORK:
132
case PK_ERROR_ENUM_NO_MORE_MIRRORS_TO_TRY:
133
case PK_ERROR_ENUM_CANNOT_FETCH_SOURCES:
134
/* TRANSLATORS: the package manager needed to download
135
* something with no network available */
136
g_string_append (msg, _("Network access was required but not available."));
138
case PK_ERROR_ENUM_BAD_GPG_SIGNATURE:
139
case PK_ERROR_ENUM_CANNOT_UPDATE_REPO_UNSIGNED:
140
case PK_ERROR_ENUM_GPG_FAILURE:
141
case PK_ERROR_ENUM_MISSING_GPG_SIGNATURE:
142
case PK_ERROR_ENUM_PACKAGE_CORRUPT:
143
/* TRANSLATORS: if the package is not signed correctly
145
g_string_append (msg, _("An update was not signed in the correct way."));
148
case PK_ERROR_ENUM_DEP_RESOLUTION_FAILED:
149
case PK_ERROR_ENUM_FILE_CONFLICTS:
150
case PK_ERROR_ENUM_INCOMPATIBLE_ARCHITECTURE:
151
case PK_ERROR_ENUM_PACKAGE_CONFLICTS:
152
/* TRANSLATORS: the transaction failed in a way the user
153
* probably cannot comprehend. Package management systems
154
* really are teh suck.*/
155
g_string_append (msg, _("The update could not be completed."));
158
case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
159
/* TRANSLATORS: the user aborted the update manually */
160
g_string_append (msg, _("The update was cancelled."));
162
case PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE:
163
case PK_ERROR_ENUM_UPDATE_NOT_FOUND:
164
/* TRANSLATORS: the user must have updated manually after
165
* the updates were prepared */
166
g_string_append (msg, _("An offline update was requested but no packages required updating."));
168
case PK_ERROR_ENUM_NO_SPACE_ON_DEVICE:
169
/* TRANSLATORS: we ran out of disk space */
170
g_string_append (msg, _("No space was left on the drive."));
172
case PK_ERROR_ENUM_PACKAGE_FAILED_TO_BUILD:
173
case PK_ERROR_ENUM_PACKAGE_FAILED_TO_INSTALL:
174
case PK_ERROR_ENUM_PACKAGE_FAILED_TO_REMOVE:
175
/* TRANSLATORS: the update process failed in a general
176
* way, usually this message will come from source distros
178
g_string_append (msg, _("An update failed to install correctly."));
182
/* TRANSLATORS: We didn't handle the error type */
183
g_string_append (msg, _("The offline update failed in an unexpected way."));
188
g_string_append_printf (msg, "\n%s\n\n%s",
189
/* TRANSLATORS: these are geeky messages from the
190
* package manager no mortal is supposed to understand,
191
* but google might know what they mean */
192
_("Detailed errors from the package manager follow:"),
193
pk_error_get_details (manager->priv->offline_update_error));
195
dialog = gtk_message_dialog_new (NULL,
200
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
202
g_signal_connect_swapped (dialog, "response",
203
G_CALLBACK (gtk_widget_destroy),
205
gtk_widget_show (dialog);
206
clear_offline_updates_message ();
207
g_string_free (msg, TRUE);
211
libnotify_action_cb (NotifyNotification *notification,
216
GError *error = NULL;
217
GsdUpdatesManager *manager = GSD_UPDATES_MANAGER (user_data);
219
notify_notification_close (notification, NULL);
220
if (g_strcmp0 (action, "distro-upgrade-info") == 0) {
221
ret = g_spawn_command_line_async (DATADIR "/PackageKit/pk-upgrade-distro.sh",
224
g_warning ("Failure launching pk-upgrade-distro.sh: %s",
226
g_error_free (error);
230
if (g_strcmp0 (action, "show-update-viewer") == 0) {
231
ret = g_spawn_command_line_async (BINDIR "/gpk-update-viewer",
234
g_warning ("Failure launching update viewer: %s",
236
g_error_free (error);
240
if (g_strcmp0 (action, "clear-offline-updates") == 0) {
241
clear_offline_updates_message ();
244
if (g_strcmp0 (action, "error-offline-updates") == 0) {
245
show_offline_updates_error (manager);
248
if (g_strcmp0 (action, "cancel") == 0) {
250
g_cancellable_cancel (manager->priv->cancellable);
253
g_warning ("unknown action id: %s", action);
259
on_notification_closed (NotifyNotification *notification, gpointer data)
261
g_object_unref (notification);
265
get_distro_upgrades_finished_cb (GObject *object,
267
GsdUpdatesManager *manager)
272
GError *error = NULL;
273
GPtrArray *array = NULL;
274
GString *string = NULL;
276
NotifyNotification *notification;
277
PkClient *client = PK_CLIENT(object);
278
PkDistroUpgrade *item;
279
PkError *error_code = NULL;
281
PkUpdateStateEnum state;
283
/* get the results */
284
results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
285
if (results == NULL) {
286
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
287
g_error_free (error);
290
if (error->domain != PK_CLIENT_ERROR ||
291
error->code != PK_CLIENT_ERROR_NOT_SUPPORTED) {
292
g_warning ("failed to get upgrades: %s",
295
g_error_free (error);
299
/* check error code */
300
error_code = pk_results_get_error_code (results);
301
if (error_code != NULL) {
302
g_warning ("failed to get upgrades: %s, %s",
303
pk_error_enum_to_string (pk_error_get_code (error_code)),
304
pk_error_get_details (error_code));
308
/* process results */
309
array = pk_results_get_distro_upgrade_array (results);
312
if (array->len == 0) {
313
g_debug ("no upgrades");
317
/* do we do the notification? */
318
ret = g_settings_get_boolean (manager->priv->settings_gsd,
319
GSD_SETTINGS_NOTIFY_DISTRO_UPGRADES);
321
g_debug ("ignoring due to GSettings");
325
/* find the upgrade string */
326
string = g_string_new ("");
327
for (i=0; i < array->len; i++) {
328
item = (PkDistroUpgrade *) g_ptr_array_index (array, i);
333
g_string_append_printf (string, "%s (%s)\n",
335
pk_distro_upgrade_enum_to_string (state));
338
if (string->len != 0)
339
g_string_set_size (string, string->len-1);
341
/* TRANSLATORS: a distro update is available, e.g. Fedora 8 to Fedora 9 */
342
title = _("Distribution upgrades available");
343
notification = notify_notification_new (title,
345
GSD_UPDATES_ICON_NORMAL);
346
notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
347
notify_notification_set_app_name (notification, _("Software Updates"));
348
notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
349
notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
350
notify_notification_add_action (notification, "distro-upgrade-info",
351
/* TRANSLATORS: provides more information about the upgrade */
352
_("More information"),
355
g_signal_connect (notification, "closed",
356
G_CALLBACK (on_notification_closed), NULL);
357
ret = notify_notification_show (notification, &error);
359
g_warning ("error: %s", error->message);
360
g_error_free (error);
363
if (error_code != NULL)
364
g_object_unref (error_code);
366
g_ptr_array_unref (array);
368
g_string_free (string, TRUE);
370
g_object_unref (results);
374
due_get_upgrades_cb (GsdUpdatesRefresh *refresh, GsdUpdatesManager *manager)
376
/* optimize the amount of downloaded data by setting the cache age */
377
pk_client_set_cache_age (PK_CLIENT(manager->priv->task),
378
g_settings_get_int (manager->priv->settings_gsd,
379
GSD_SETTINGS_FREQUENCY_GET_UPGRADES));
381
/* get new distro upgrades list */
382
pk_client_get_distro_upgrades_async (PK_CLIENT(manager->priv->task),
385
(GAsyncReadyCallback) get_distro_upgrades_finished_cb,
390
refresh_cache_finished_cb (GObject *object, GAsyncResult *res, GsdUpdatesManager *manager)
392
PkClient *client = PK_CLIENT(object);
394
GError *error = NULL;
395
PkError *error_code = NULL;
397
/* get the results */
398
results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
399
if (results == NULL) {
400
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
401
g_error_free (error);
404
g_warning ("failed to refresh the cache: %s",
406
g_error_free (error);
410
/* check error code */
411
error_code = pk_results_get_error_code (results);
412
if (error_code != NULL) {
413
g_warning ("failed to refresh the cache: %s, %s",
414
pk_error_enum_to_string (pk_error_get_code (error_code)),
415
pk_error_get_details (error_code));
418
if (error_code != NULL)
419
g_object_unref (error_code);
421
g_object_unref (results);
425
due_refresh_cache_cb (GsdUpdatesRefresh *refresh, GsdUpdatesManager *manager)
427
/* optimize the amount of downloaded data by setting the cache age */
428
pk_client_set_cache_age (PK_CLIENT(manager->priv->task),
429
g_settings_get_int (manager->priv->settings_gsd,
430
GSD_SETTINGS_FREQUENCY_REFRESH_CACHE));
432
pk_client_refresh_cache_async (PK_CLIENT(manager->priv->task),
436
(GAsyncReadyCallback) refresh_cache_finished_cb,
441
notify_critical_updates (GsdUpdatesManager *manager, GPtrArray *array)
443
const gchar *message;
446
GError *error = NULL;
447
NotifyNotification *notification;
449
/* if the number of critical updates is the same as the last notification,
450
* then skip the notifcation as we don't want to bombard the user every hour */
451
if (array->len == manager->priv->number_updates_critical_last_shown) {
452
g_debug ("ignoring as user ignored last warning");
456
/* save for comparison later */
457
manager->priv->number_updates_critical_last_shown = array->len;
459
/* TRANSLATORS: title in the libnotify popup */
460
title = ngettext ("Update", "Updates", array->len);
462
/* TRANSLATORS: message when there are security updates */
463
message = ngettext ("An important software update is available",
464
"Important software updates are available", array->len);
466
/* close any existing notification */
467
if (manager->priv->notification_updates != NULL) {
468
notify_notification_close (manager->priv->notification_updates, NULL);
469
manager->priv->notification_updates = NULL;
473
g_debug ("title=%s, message=%s", title, message);
474
notification = notify_notification_new (title,
476
GSD_UPDATES_ICON_URGENT);
477
notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
478
notify_notification_set_app_name (notification, _("Software Updates"));
479
notify_notification_set_timeout (notification, 15000);
480
notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
481
notify_notification_add_action (notification, "show-update-viewer",
482
/* TRANSLATORS: button: open the update viewer to install updates*/
483
_("Install updates"), libnotify_action_cb, manager, NULL);
484
g_signal_connect (notification, "closed",
485
G_CALLBACK (on_notification_closed), NULL);
486
ret = notify_notification_show (notification, &error);
488
g_warning ("error: %s", error->message);
489
g_error_free (error);
491
/* track so we can prevent doubled notifications */
492
manager->priv->notification_updates = notification;
493
g_object_add_weak_pointer (G_OBJECT (manager->priv->notification_updates),
494
(void **) &manager->priv->notification_updates);
498
notify_normal_updates_maybe (GsdUpdatesManager *manager, GPtrArray *array)
500
const gchar *message;
503
GError *error = NULL;
504
guint64 time_last_notify;
506
guint freq_updates_notify;
507
NotifyNotification *notification;
509
/* find out if enough time has passed since the last notification */
510
time_now = g_get_real_time () / 1000000;
511
freq_updates_notify = g_settings_get_int (manager->priv->settings_gsd,
512
GSD_SETTINGS_FREQUENCY_UPDATES_NOTIFICATION);
513
g_settings_get (manager->priv->settings_gsd,
514
GSD_SETTINGS_LAST_UPDATES_NOTIFICATION,
515
"t", &time_last_notify);
516
if (time_last_notify > 0 &&
517
(guint64) freq_updates_notify > time_now - time_last_notify) {
518
g_debug ("not showing non-critical notification as already shown %i hours ago",
519
(guint) (time_now - time_last_notify) / (60 * 60));
523
/* TRANSLATORS: title in the libnotify popup */
524
title = ngettext ("Update", "Updates", array->len);
526
/* TRANSLATORS: message when there are non-security updates */
527
message = ngettext ("A software update is available.",
528
"Software updates are available.", array->len);
530
/* close any existing notification */
531
if (manager->priv->notification_updates != NULL) {
532
notify_notification_close (manager->priv->notification_updates, NULL);
533
manager->priv->notification_updates = NULL;
537
g_debug ("title=%s, message=%s", title, message);
538
notification = notify_notification_new (title,
540
GSD_UPDATES_ICON_NORMAL);
541
notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
542
notify_notification_set_app_name (notification, _("Software Updates"));
543
notify_notification_set_timeout (notification, 15000);
544
notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
545
notify_notification_add_action (notification, "show-update-viewer",
546
/* TRANSLATORS: button: open the update viewer to install updates*/
547
_("Install updates"), libnotify_action_cb, manager, NULL);
548
g_signal_connect (notification, "closed",
549
G_CALLBACK (on_notification_closed), NULL);
550
ret = notify_notification_show (notification, &error);
552
g_warning ("error: %s", error->message);
553
g_error_free (error);
556
/* reset notification time */
557
g_settings_set (manager->priv->settings_gsd,
558
GSD_SETTINGS_LAST_UPDATES_NOTIFICATION,
561
/* track so we can prevent doubled notifications */
562
manager->priv->notification_updates = notification;
563
g_object_add_weak_pointer (G_OBJECT (manager->priv->notification_updates),
564
(void **) &manager->priv->notification_updates);
568
notify_failed_get_updates_maybe (GsdUpdatesManager *manager)
571
const gchar *message;
574
GError *error = NULL;
575
NotifyNotification *notification;
577
/* give the user a break */
578
if (manager->priv->failed_get_updates_count++ < MAX_FAILED_GET_UPDATES) {
579
g_debug ("failed GetUpdates, but will retry %i more times before notification",
580
MAX_FAILED_GET_UPDATES - manager->priv->failed_get_updates_count);
584
/* TRANSLATORS: the updates mechanism */
585
title = _("Updates");
587
/* TRANSLATORS: we failed to get the updates multiple times,
588
* and now we need to inform the user that something might be wrong */
589
message = _("Unable to access software updates");
591
/* TRANSLATORS: try again, this time launching the update viewer */
592
button = _("Try again");
594
notification = notify_notification_new (title,
596
GSD_UPDATES_ICON_NORMAL);
597
notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
598
notify_notification_set_app_name (notification, _("Software Updates"));
599
notify_notification_set_timeout (notification, 120*1000);
600
notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
601
notify_notification_add_action (notification, "show-update-viewer",
605
g_signal_connect (notification, "closed",
606
G_CALLBACK (on_notification_closed), NULL);
607
ret = notify_notification_show (notification, &error);
609
g_warning ("failed to show notification: %s",
611
g_error_free (error);
614
/* reset, even if the message failed */
615
manager->priv->failed_get_updates_count = 0;
619
check_updates_for_importance (GsdUpdatesManager *manager)
623
GPtrArray *important_array;
625
/* check each package */
626
important_array = g_ptr_array_new ();
627
for (i = 0; i < manager->priv->update_packages->len; i++) {
628
pkg = g_ptr_array_index (manager->priv->update_packages, i);
629
if (pk_package_get_info (pkg) == PK_INFO_ENUM_SECURITY ||
630
pk_package_get_info (pkg) == PK_INFO_ENUM_IMPORTANT)
631
g_ptr_array_add (important_array, pkg);
633
if (important_array->len > 0) {
634
notify_critical_updates (manager,
637
notify_normal_updates_maybe (manager,
638
manager->priv->update_packages);
640
g_ptr_array_unref (important_array);
644
package_download_finished_cb (GObject *object,
646
GsdUpdatesManager *manager)
648
PkClient *client = PK_CLIENT(object);
650
GError *error = NULL;
651
PkError *error_code = NULL;
653
/* get the results */
654
results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
655
if (results == NULL) {
656
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
657
g_error_free (error);
660
g_warning ("failed to download: %s",
662
g_error_free (error);
663
notify_failed_get_updates_maybe (manager);
667
/* check error code */
668
error_code = pk_results_get_error_code (results);
669
if (error_code != NULL) {
670
g_warning ("failed to download: %s, %s",
671
pk_error_enum_to_string (pk_error_get_code (error_code)),
672
pk_error_get_details (error_code));
673
switch (pk_error_get_code (error_code)) {
674
case PK_ERROR_ENUM_CANCELLED_PRIORITY:
675
case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
676
g_debug ("ignoring error");
679
notify_failed_get_updates_maybe (manager);
685
/* check to see if should notify */
686
check_updates_for_importance (manager);
689
if (error_code != NULL)
690
g_object_unref (error_code);
692
g_object_unref (results);
696
auto_download_updates (GsdUpdatesManager *manager)
702
/* download each package */
703
package_ids = g_new0 (gchar *, manager->priv->update_packages->len + 1);
704
for (i = 0; i < manager->priv->update_packages->len; i++) {
705
pkg = g_ptr_array_index (manager->priv->update_packages, i);
706
package_ids[i] = g_strdup (pk_package_get_id (pkg));
709
#if PK_CHECK_VERSION(0,8,1)
710
/* we've set only-download in PkTask */
711
pk_task_update_packages_async (manager->priv->task,
713
manager->priv->cancellable,
715
(GAsyncReadyCallback) package_download_finished_cb,
718
/* download them all */
719
pk_client_download_packages_async (PK_CLIENT(manager->priv->task),
721
NULL, /* this means system cache */
722
manager->priv->cancellable,
724
(GAsyncReadyCallback) package_download_finished_cb,
727
g_strfreev (package_ids);
731
get_updates_finished_cb (GObject *object,
733
GsdUpdatesManager *manager)
735
PkClient *client = PK_CLIENT(object);
737
GError *error = NULL;
739
PkError *error_code = NULL;
741
/* get the results */
742
results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
743
if (results == NULL) {
744
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
745
g_error_free (error);
748
g_warning ("failed to get updates: %s",
750
g_error_free (error);
751
notify_failed_get_updates_maybe (manager);
755
/* check error code */
756
error_code = pk_results_get_error_code (results);
757
if (error_code != NULL) {
758
g_warning ("failed to get updates: %s, %s",
759
pk_error_enum_to_string (pk_error_get_code (error_code)),
760
pk_error_get_details (error_code));
761
switch (pk_error_get_code (error_code)) {
762
case PK_ERROR_ENUM_CANCELLED_PRIORITY:
763
case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
764
g_debug ("ignoring error");
767
notify_failed_get_updates_maybe (manager);
773
/* we succeeded, so clear the count */
774
manager->priv->failed_get_updates_count = 0;
776
/* so we can download or check for important & security updates */
777
if (manager->priv->update_packages != NULL)
778
g_ptr_array_unref (manager->priv->update_packages);
779
manager->priv->update_packages = pk_results_get_package_array (results);
781
/* we have no updates */
782
if (manager->priv->update_packages->len == 0) {
783
g_debug ("no updates");
787
/* should we auto-download the updates? */
788
ret = g_settings_get_boolean (manager->priv->settings_gsd,
789
GSD_SETTINGS_AUTO_DOWNLOAD_UPDATES);
791
auto_download_updates (manager);
795
/* just check to see if should notify */
796
check_updates_for_importance (manager);
798
if (error_code != NULL)
799
g_object_unref (error_code);
801
g_object_unref (results);
805
query_updates (GsdUpdatesManager *manager)
807
/* optimize the amount of downloaded data by setting the cache age */
808
pk_client_set_cache_age (PK_CLIENT(manager->priv->task),
809
g_settings_get_int (manager->priv->settings_gsd,
810
GSD_SETTINGS_FREQUENCY_GET_UPDATES));
812
/* get new update list */
813
pk_client_get_updates_async (PK_CLIENT(manager->priv->task),
814
pk_bitfield_value (PK_FILTER_ENUM_NONE),
815
manager->priv->cancellable,
817
(GAsyncReadyCallback) get_updates_finished_cb,
822
due_get_updates_cb (GsdUpdatesRefresh *refresh, GsdUpdatesManager *manager)
824
query_updates (manager);
828
get_proxy_http (GsdUpdatesManager *manager)
832
gchar *password = NULL;
834
gchar *username = NULL;
835
GString *string = NULL;
837
GDesktopProxyMode proxy_mode;
839
proxy_mode = g_settings_get_enum (manager->priv->settings_proxy, "mode");
840
if (proxy_mode != G_DESKTOP_PROXY_MODE_MANUAL)
843
host = g_settings_get_string (manager->priv->settings_http,
847
port = g_settings_get_int (manager->priv->settings_http,
850
/* use an HTTP auth string? */
851
ret = g_settings_get_boolean (manager->priv->settings_http,
852
"use-authentication");
854
username = g_settings_get_string (manager->priv->settings_http,
855
"authentication-user");
856
password = g_settings_get_string (manager->priv->settings_http,
857
"authentication-password");
860
/* make PackageKit proxy string */
861
string = g_string_new (host);
863
g_string_append_printf (string, ":%i", port);
864
if (username != NULL && password != NULL)
865
g_string_append_printf (string, "@%s:%s", username, password);
866
else if (username != NULL)
867
g_string_append_printf (string, "@%s", username);
868
else if (password != NULL)
869
g_string_append_printf (string, "@:%s", password);
870
proxy = g_string_free (string, FALSE);
879
get_proxy_ftp (GsdUpdatesManager *manager)
883
GString *string = NULL;
885
GDesktopProxyMode proxy_mode;
887
proxy_mode = g_settings_get_enum (manager->priv->settings_proxy, "mode");
888
if (proxy_mode != G_DESKTOP_PROXY_MODE_MANUAL)
891
host = g_settings_get_string (manager->priv->settings_ftp,
895
port = g_settings_get_int (manager->priv->settings_ftp,
900
/* make PackageKit proxy string */
901
string = g_string_new (host);
903
g_string_append_printf (string, ":%i", port);
904
proxy = g_string_free (string, FALSE);
912
set_proxy_cb (GObject *object, GAsyncResult *res, gpointer user_data)
915
GError *error = NULL;
916
PkControl *control = PK_CONTROL (object);
919
ret = pk_control_set_proxy_finish (control, res, &error);
921
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
922
g_warning ("failed to set proxies: %s", error->message);
923
g_error_free (error);
928
reload_proxy_settings (GsdUpdatesManager *manager)
933
proxy_http = get_proxy_http (manager);
934
proxy_ftp = get_proxy_ftp (manager);
937
pk_control_set_proxy_async (manager->priv->control,
949
settings_changed_cb (GSettings *settings,
951
GsdUpdatesManager *manager)
953
reload_proxy_settings (manager);
957
settings_gsd_changed_cb (GSettings *settings,
959
GsdUpdatesManager *manager)
964
session_inhibit (GsdUpdatesManager *manager)
967
GError *error = NULL;
968
GVariant *retval = NULL;
970
/* state invalid somehow */
971
if (manager->priv->inhibit_cookie != 0) {
972
g_warning ("already locked");
976
/* TRANSLATORS: the reason why we've inhibited it */
977
reason = _("A transaction that cannot be interrupted is running");
978
retval = g_dbus_proxy_call_sync (G_DBUS_PROXY (manager->priv->proxy_session),
980
g_variant_new ("(susu)",
981
"gnome-settings-daemon", /* app-id */
985
G_DBUS_CALL_FLAGS_NONE,
987
manager->priv->cancellable,
989
if (retval == NULL) {
990
g_warning ("failed to inhibit gnome-session: %s",
992
g_error_free (error);
997
g_variant_get (retval, "(u)",
998
&manager->priv->inhibit_cookie);
1001
g_variant_unref (retval);
1005
session_uninhibit (GsdUpdatesManager *manager)
1007
GError *error = NULL;
1008
GVariant *retval = NULL;
1010
/* state invalid somehow */
1011
if (manager->priv->inhibit_cookie == 0) {
1012
g_warning ("not locked");
1015
retval = g_dbus_proxy_call_sync (G_DBUS_PROXY (manager->priv->proxy_session),
1017
g_variant_new ("(u)",
1018
manager->priv->inhibit_cookie),
1019
G_DBUS_CALL_FLAGS_NONE,
1021
manager->priv->cancellable,
1023
if (retval == NULL) {
1024
g_warning ("failed to uninhibit gnome-session: %s",
1026
g_error_free (error);
1030
manager->priv->inhibit_cookie = 0;
1032
g_variant_unref (retval);
1036
notify_locked_cb (PkControl *control,
1038
GsdUpdatesManager *manager)
1042
g_object_get (control, "locked", &locked, NULL);
1044
/* TODO: locked is a bit harsh, we can probably still allow
1045
* reboot when packages are downloading or the transaction is
1048
session_inhibit (manager);
1050
session_uninhibit (manager);
1055
update_viewer_appeared_cb (GDBusConnection *connection,
1057
const gchar *name_owner,
1060
GsdUpdatesManager *manager = GSD_UPDATES_MANAGER (user_data);
1062
/* close any existing notification */
1063
if (manager->priv->notification_updates != NULL) {
1064
g_debug ("update viewer on the bus, clearing bubble");
1065
notify_notification_close (manager->priv->notification_updates, NULL);
1066
manager->priv->notification_updates = NULL;
1071
file_exists_in_root (const gchar *root, const gchar *filename)
1073
gboolean ret = FALSE;
1077
source_path = g_build_filename (root, filename, NULL);
1078
source = g_file_new_for_path (source_path);
1080
/* ignore virtual mountpoints */
1081
if (!g_file_is_native (source))
1084
/* an interesting file exists */
1085
ret = g_file_query_exists (source, NULL);
1086
g_debug ("checking for %s: %s", source_path, ret ? "yes" : "no");
1090
g_free (source_path);
1091
g_object_unref (source);
1096
mount_added_cb (GVolumeMonitor *volume_monitor,
1098
GsdUpdatesManager *manager)
1100
gboolean ret = FALSE;
1101
gchar **filenames = NULL;
1102
gchar *media_repo_filenames;
1107
/* check if any installed media is an install disk */
1108
root = g_mount_get_root (mount);
1109
root_path = g_file_get_path (root);
1112
media_repo_filenames = g_settings_get_string (manager->priv->settings_gsd,
1113
GSD_SETTINGS_MEDIA_REPO_FILENAMES);
1114
if (media_repo_filenames == NULL) {
1115
g_warning ("failed to get media repo filenames");
1119
/* search each possible filename */
1120
filenames = g_strsplit (media_repo_filenames, ",", -1);
1121
for (i=0; filenames[i] != NULL; i++) {
1122
ret = file_exists_in_root (root_path, filenames[i]);
1127
/* do an updates check with the new media */
1129
query_updates (manager);
1131
g_strfreev (filenames);
1132
g_free (media_repo_filenames);
1134
g_object_unref (root);
1137
#define PK_OFFLINE_UPDATE_RESULTS_GROUP "PackageKit Offline Update Results"
1138
#define PK_OFFLINE_UPDATE_RESULTS_FILENAME "/var/lib/PackageKit/offline-update-competed"
1141
check_offline_update_cb (gpointer user_data)
1143
const gchar *message;
1147
gchar *error_code = NULL;
1148
gchar *error_details = NULL;
1149
gchar *packages = NULL;
1150
GError *error = NULL;
1151
GKeyFile *key_file = NULL;
1152
GsdUpdatesManager *manager = (GsdUpdatesManager *) user_data;
1154
guint num_packages = 1;
1155
NotifyNotification *notification;
1156
PkErrorEnum error_enum = PK_ERROR_ENUM_UNKNOWN;
1158
/* was any offline update attempted */
1159
if (!g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS))
1162
/* open the file and see what happened */
1163
key_file = g_key_file_new ();
1164
ret = g_key_file_load_from_file (key_file,
1165
PK_OFFLINE_UPDATE_RESULTS_FILENAME,
1169
g_warning ("failed to open %s: %s",
1170
PK_OFFLINE_UPDATE_RESULTS_FILENAME,
1172
g_error_free (error);
1175
success = g_key_file_get_boolean (key_file,
1176
PK_OFFLINE_UPDATE_RESULTS_GROUP,
1180
packages = g_key_file_get_string (key_file,
1181
PK_OFFLINE_UPDATE_RESULTS_GROUP,
1184
if (packages == NULL) {
1185
g_warning ("No 'Packages' in %s",
1186
PK_OFFLINE_UPDATE_RESULTS_FILENAME);
1190
/* count the packages for translators */
1191
for (i = 0; packages[i] != '\0'; i++) {
1192
if (packages[i] == ',')
1196
/* TRANSLATORS: title in the libnotify popup */
1197
title = ngettext ("Software Update Installed",
1198
"Software Updates Installed",
1201
/* TRANSLATORS: message when we've done offline updates */
1202
message = ngettext ("An important OS update has been installed.",
1203
"Important OS updates have been installed.",
1206
/* no need to keep the file around anymore */
1207
clear_offline_updates_message ();
1209
/* get error details */
1210
manager->priv->offline_update_error = pk_error_new ();
1212
error_code = g_key_file_get_string (key_file,
1213
PK_OFFLINE_UPDATE_RESULTS_GROUP,
1216
if (error_code != NULL)
1217
error_enum = pk_error_enum_from_string (error_code);
1218
error_details = g_key_file_get_string (key_file,
1219
PK_OFFLINE_UPDATE_RESULTS_GROUP,
1222
g_object_set (manager->priv->offline_update_error,
1224
"details", error_details,
1227
/* TRANSLATORS: title in the libnotify popup */
1228
title = _("Software Updates Failed");
1230
/* TRANSLATORS: message when we've not done offline updates */
1231
message = _("An important OS update failed to be installed.");
1235
g_debug ("title=%s, message=%s", title, message);
1236
notification = notify_notification_new (title,
1238
GSD_UPDATES_ICON_URGENT);
1239
notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
1240
notify_notification_set_app_name (notification, _("Software Updates"));
1241
notify_notification_set_timeout (notification, -1);
1242
notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
1245
notify_notification_add_action (notification, "review-offline-updates",
1246
/* TRANSLATORS: button: review the offline update changes */
1247
_("Review"), libnotify_action_cb, manager, NULL);
1250
notify_notification_add_action (notification, "error-offline-updates",
1251
/* TRANSLATORS: button: review the offline update changes */
1252
_("Show details"), libnotify_action_cb, manager, NULL);
1254
notify_notification_add_action (notification, "clear-offline-updates",
1255
/* TRANSLATORS: button: clear notification */
1256
_("OK"), libnotify_action_cb, manager, NULL);
1257
g_signal_connect (notification, "closed",
1258
G_CALLBACK (on_notification_closed), NULL);
1259
ret = notify_notification_show (notification, &error);
1261
g_warning ("error: %s", error->message);
1262
g_error_free (error);
1266
g_free (error_code);
1267
g_free (error_details);
1268
if (key_file != NULL)
1269
g_key_file_free (key_file);
1270
manager->priv->offline_update_id = 0;
1275
gsd_updates_manager_start (GsdUpdatesManager *manager,
1278
gboolean ret = FALSE;
1280
g_debug ("Starting updates manager");
1282
/* use PackageKit */
1283
manager->priv->cancellable = g_cancellable_new ();
1284
manager->priv->control = pk_control_new ();
1285
g_signal_connect (manager->priv->control, "notify::locked",
1286
G_CALLBACK (notify_locked_cb), manager);
1287
manager->priv->task = pk_task_new ();
1288
g_object_set (manager->priv->task,
1290
"interactive", FALSE,
1291
#if PK_CHECK_VERSION(0,8,1)
1292
"only-download", TRUE,
1296
/* watch UDev for missing firmware */
1297
manager->priv->firmware = gsd_updates_firmware_new ();
1299
/* get automatic callbacks about when we should check for
1300
* updates, refresh-caches and upgrades */
1301
manager->priv->refresh = gsd_updates_refresh_new ();
1302
g_signal_connect (manager->priv->refresh, "get-upgrades",
1303
G_CALLBACK (due_get_upgrades_cb), manager);
1304
g_signal_connect (manager->priv->refresh, "refresh-cache",
1305
G_CALLBACK (due_refresh_cache_cb), manager);
1306
g_signal_connect (manager->priv->refresh, "get-updates",
1307
G_CALLBACK (due_get_updates_cb), manager);
1309
/* get proxy settings */
1310
manager->priv->settings_proxy = g_settings_new ("org.gnome.system.proxy");
1311
g_signal_connect (manager->priv->settings_proxy, "changed",
1312
G_CALLBACK (settings_changed_cb), manager);
1314
/* get http settings */
1315
manager->priv->settings_http = g_settings_new ("org.gnome.system.proxy.http");
1316
g_signal_connect (manager->priv->settings_http, "changed",
1317
G_CALLBACK (settings_changed_cb), manager);
1319
/* get ftp settings */
1320
manager->priv->settings_ftp = g_settings_new ("org.gnome.system.proxy.ftp");
1321
g_signal_connect (manager->priv->settings_ftp, "changed",
1322
G_CALLBACK (settings_changed_cb), manager);
1324
/* get ftp settings */
1325
manager->priv->settings_gsd = g_settings_new ("org.gnome.settings-daemon.plugins.updates");
1326
g_signal_connect (manager->priv->settings_gsd, "changed",
1327
G_CALLBACK (settings_gsd_changed_cb), manager);
1329
/* use gnome-session for the idle detection */
1330
manager->priv->proxy_session =
1331
gnome_settings_bus_get_session_proxy ();
1332
if (manager->priv->proxy_session == NULL)
1335
/* if the update viewer is started, then hide the notification */
1336
manager->priv->update_viewer_watcher_id =
1337
g_bus_watch_name (G_BUS_TYPE_SESSION,
1338
"org.freedesktop.PackageKit.UpdateViewer",
1339
G_BUS_NAME_WATCHER_FLAGS_NONE,
1340
update_viewer_appeared_cb,
1345
/* get a volume monitor so we can watch media */
1346
manager->priv->volume_monitor = g_volume_monitor_get ();
1347
g_signal_connect (manager->priv->volume_monitor, "mount-added",
1348
G_CALLBACK (mount_added_cb), manager);
1351
reload_proxy_settings (manager);
1353
/* check for offline update */
1354
manager->priv->offline_update_id =
1355
g_timeout_add_seconds (GSD_UPDATES_CHECK_OFFLINE_TIMEOUT,
1356
check_offline_update_cb,
1361
g_debug ("Started updates manager");
1367
gsd_updates_manager_stop (GsdUpdatesManager *manager)
1369
g_debug ("Stopping updates manager");
1371
g_clear_object (&manager->priv->settings_proxy);
1372
g_clear_object (&manager->priv->settings_http);
1373
g_clear_object (&manager->priv->settings_ftp);
1374
g_clear_object (&manager->priv->settings_gsd);
1375
g_clear_object (&manager->priv->control);
1376
g_clear_object (&manager->priv->task);
1377
g_clear_object (&manager->priv->refresh);
1378
g_clear_object (&manager->priv->firmware);
1379
g_clear_object (&manager->priv->proxy_session);
1380
g_clear_object (&manager->priv->volume_monitor);
1381
if (manager->priv->cancellable) {
1382
g_cancellable_cancel (manager->priv->cancellable);
1383
g_clear_object (&manager->priv->cancellable);
1385
if (manager->priv->update_viewer_watcher_id != 0) {
1386
g_bus_unwatch_name (manager->priv->update_viewer_watcher_id);
1387
manager->priv->update_viewer_watcher_id = 0;
1389
if (manager->priv->offline_update_id) {
1390
g_source_remove (manager->priv->offline_update_id);
1391
manager->priv->offline_update_id = 0;
1393
if (manager->priv->update_packages != NULL) {
1394
g_ptr_array_unref (manager->priv->update_packages);
1395
manager->priv->update_packages = NULL;
1397
g_clear_object (&manager->priv->offline_update_error);
1401
gsd_updates_manager_constructor (
1403
guint n_construct_properties,
1404
GObjectConstructParam *construct_properties)
1406
GsdUpdatesManager *m;
1408
m = GSD_UPDATES_MANAGER (G_OBJECT_CLASS (gsd_updates_manager_parent_class)->constructor (
1410
n_construct_properties,
1411
construct_properties));
1413
return G_OBJECT (m);
1417
gsd_updates_manager_dispose (GObject *object)
1419
GsdUpdatesManager *manager;
1421
manager = GSD_UPDATES_MANAGER (object);
1423
gsd_updates_manager_stop (manager);
1425
G_OBJECT_CLASS (gsd_updates_manager_parent_class)->dispose (object);
1429
gsd_updates_manager_class_init (GsdUpdatesManagerClass *klass)
1431
GObjectClass *object_class = G_OBJECT_CLASS (klass);
1433
object_class->constructor = gsd_updates_manager_constructor;
1434
object_class->dispose = gsd_updates_manager_dispose;
1436
g_type_class_add_private (klass, sizeof (GsdUpdatesManagerPrivate));
1440
gsd_updates_manager_init (GsdUpdatesManager *manager)
1442
manager->priv = GSD_UPDATES_MANAGER_GET_PRIVATE (manager);
1446
gsd_updates_manager_new (void)
1448
if (manager_object) {
1449
g_object_ref (manager_object);
1451
manager_object = g_object_new (GSD_TYPE_UPDATES_MANAGER, NULL);
1452
g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object);
1455
return GSD_UPDATES_MANAGER (manager_object);