Merge lp:~ddieter/appcenter/appcenter-notify-restart into lp:~elementary-apps/appcenter/appcenter

Proposed by Dieter Debast
Status: Rejected
Rejected by: Danielle Foré
Proposed branch: lp:~ddieter/appcenter/appcenter-notify-restart
Merge into: lp:~elementary-apps/appcenter/appcenter
Diff against target: 328 lines (+176/-12)
6 files modified
src/CMakeLists.txt (+2/-0)
src/Core/Client.vala (+24/-0)
src/Services/DbusInterfaces.vala (+24/-0)
src/Views/AppListView.vala (+23/-2)
src/Widgets/RestartDialog.vala (+87/-0)
src/Widgets/UpdateHeaderRow.vala (+16/-10)
To merge this branch: bzr merge lp:~ddieter/appcenter/appcenter-notify-restart
Reviewer Review Type Date Requested Status
elementary Apps team Pending
Review via email: mp+317155@code.launchpad.net

Description of the change

After installing updates or periodically when updating the cache, appcenter checks for the existence of the /var/run/reboot-required file. This file is created by an applications post-installation script to indicate that a reboot is necessary.

If this file exists, appcenter shows a notification and the "Up to Date" text is changed to "Restart required". There's also a "Restart now" button that shows a confirmation dialog and allows the user to restart the device.

To post a comment you must log in.
Revision history for this message
Danielle Foré (danrabbit) wrote :

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2017-02-10 20:15:32 +0000
+++ src/CMakeLists.txt 2017-02-13 23:26:06 +0000
@@ -23,6 +23,8 @@
23 Widgets/AppListRow.vala23 Widgets/AppListRow.vala
24 Widgets/AppActionButton.vala24 Widgets/AppActionButton.vala
25 Widgets/UpdateHeaderRow.vala25 Widgets/UpdateHeaderRow.vala
26 Widgets/RestartDialog.vala
27 Services/DbusInterfaces.vala
26 ${CMAKE_CURRENT_BINARY_DIR}/config.vala28 ${CMAKE_CURRENT_BINARY_DIR}/config.vala
27PACKAGES29PACKAGES
28 appstream30 appstream
2931
=== modified file 'src/Core/Client.vala'
--- src/Core/Client.vala 2017-02-04 17:18:30 +0000
+++ src/Core/Client.vala 2017-02-13 23:26:06 +0000
@@ -17,6 +17,8 @@
17public class AppCenterCore.Client : Object {17public class AppCenterCore.Client : Object {
18 public signal void updates_available ();18 public signal void updates_available ();
1919
20 private const string RESTART_REQUIRED_FILE = "/var/run/reboot-required";
21
20 public bool connected { public get; private set; }22 public bool connected { public get; private set; }
21 public bool updating_cache { public get; private set; }23 public bool updating_cache { public get; private set; }
22 public uint task_count { public get; private set; default = 0; }24 public uint task_count { public get; private set; default = 0; }
@@ -29,6 +31,7 @@
29 private GLib.DateTime last_cache_update;31 private GLib.DateTime last_cache_update;
30 private uint updates_number = 0U;32 private uint updates_number = 0U;
31 private uint update_cache_timeout_id = 0;33 private uint update_cache_timeout_id = 0;
34 private bool restart_required = false;
32 private bool refresh_in_progress = false;35 private bool refresh_in_progress = false;
3336
34 private const int SECONDS_BETWEEN_REFRESHES = 60*60*24;37 private const int SECONDS_BETWEEN_REFRESHES = 60*60*24;
@@ -354,6 +357,25 @@
354 task_count--;357 task_count--;
355 refresh_in_progress = false;358 refresh_in_progress = false;
356 }359 }
360
361 public async bool check_restart () {
362 if (FileUtils.test (RESTART_REQUIRED_FILE, FileTest.EXISTS)) {
363 if (!restart_required) {
364 string title = _("Restart Required");
365 string body = _("Please restart your system to finalize updates");
366 var notification = new Notification (title);
367 notification.set_body (body);
368 notification.set_icon (new ThemedIcon ("system-software-install"));
369 notification.set_default_action ("app.open-application");
370 Application.get_default ().send_notification ("restart", notification);
371 }
372
373 restart_required = true;
374 return true;
375 }
376
377 return false;
378 }
357379
358 public uint get_package_count (GLib.GenericArray<weak Pk.Package> package_array) {380 public uint get_package_count (GLib.GenericArray<weak Pk.Package> package_array) {
359 bool os_update_found = false;381 bool os_update_found = false;
@@ -436,6 +458,8 @@
436 } else {458 } else {
437 refresh_in_progress = false; //Stops new timeout while no network.459 refresh_in_progress = false; //Stops new timeout while no network.
438 }460 }
461
462 check_restart.begin ();
439 } else {463 } else {
440 debug ("Too soon to refresh and not forced");464 debug ("Too soon to refresh and not forced");
441 }465 }
442466
=== added directory 'src/Services'
=== added file 'src/Services/DbusInterfaces.vala'
--- src/Services/DbusInterfaces.vala 1970-01-01 00:00:00 +0000
+++ src/Services/DbusInterfaces.vala 2017-02-13 23:26:06 +0000
@@ -0,0 +1,24 @@
1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2/*-
3 * Copyright (c) 2014-2016 elementary LLC. (https://elementary.io)
4 *
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 3 of the License, or
8 * (at your option) any later version.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Power and system control */
20[DBus (name = "org.freedesktop.login1.Manager")]
21interface SystemInterface : Object {
22 public abstract void reboot (bool interactive) throws IOError;
23}
24
025
=== modified file 'src/Views/AppListView.vala'
--- src/Views/AppListView.vala 2017-02-04 17:18:30 +0000
+++ src/Views/AppListView.vala 2017-02-13 23:26:06 +0000
@@ -37,6 +37,7 @@
37 private Widgets.UpdateHeaderRow updates_header;37 private Widgets.UpdateHeaderRow updates_header;
38 private Widgets.UpdateHeaderRow updated_header;38 private Widgets.UpdateHeaderRow updated_header;
39 private Widgets.AppActionButton update_all_button;39 private Widgets.AppActionButton update_all_button;
40 private Widgets.AppActionButton restart_button;
40 private bool updating_all_apps = false;41 private bool updating_all_apps = false;
41 private bool apps_remaining_started = false;42 private bool apps_remaining_started = false;
42 private GLib.Mutex update_mutex;43 private GLib.Mutex update_mutex;
@@ -66,11 +67,21 @@
66 update_all_button.clicked.connect (on_update_all);67 update_all_button.clicked.connect (on_update_all);
67 update_all_button.no_show_all = true;68 update_all_button.no_show_all = true;
68 action_button_group.add_widget (update_all_button);69 action_button_group.add_widget (update_all_button);
70
71 restart_button = new Widgets.AppActionButton (_("Restart Now"));
72 restart_button.set_suggested_action_header ();
73 restart_button.clicked.connect (() => {
74 var dialog = new Widgets.RestartDialog ();
75 dialog.show_all ();
76 });
77 restart_button.no_show_all = true;
78 action_button_group.add_widget (restart_button);
6979
70 updates_header = new Widgets.UpdateHeaderRow.updates ();80 updates_header = new Widgets.UpdateHeaderRow.updates ();
71 updates_header.add_widget (update_all_button);81 updates_header.add_widget (update_all_button);
7282
73 updated_header = new Widgets.UpdateHeaderRow.updated ();83 updated_header = new Widgets.UpdateHeaderRow.updated ();
84 updated_header.add_widget (restart_button);
7485
75 list_box.add (updates_header);86 list_box.add (updates_header);
76 list_box.add (updated_header);87 list_box.add (updated_header);
@@ -256,12 +267,22 @@
256 }267 }
257 }268 }
258269
259 updates_header.update (update_numbers, update_real_size, updating_cache);270 updates_header.update (update_numbers, update_real_size, updating_cache, false);
260 update_all_button.visible = !updating_cache && update_numbers > 0;271 update_all_button.visible = !updating_cache && update_numbers > 0;
261 }272 }
262273
263 private void update_updated_grid () {274 private void update_updated_grid () {
264 updated_header.update (0, 0, updating_cache);275 if (!updating_all_apps && !updating_cache) {
276 var client = AppCenterCore.Client.get_default ();
277 client.check_restart.begin ((obj, res) => {
278 var restart_required = client.check_restart.end (res);
279
280 updated_header.update (0, 0, updating_cache, restart_required);
281 restart_button.visible = restart_required;
282 });
283 } else {
284 updated_header.update (0, 0, updating_cache, false);
285 }
265 }286 }
266 }287 }
267}288}
268289
=== added file 'src/Widgets/RestartDialog.vala'
--- src/Widgets/RestartDialog.vala 1970-01-01 00:00:00 +0000
+++ src/Widgets/RestartDialog.vala 2017-02-13 23:26:06 +0000
@@ -0,0 +1,87 @@
1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2/*-
3 * Copyright (c) 2014-2016 elementary LLC. (https://elementary.io)
4 *
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 3 of the License, or
8 * (at your option) any later version.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19namespace AppCenter.Widgets {
20 public class RestartDialog : Gtk.Dialog {
21 private SystemInterface system_interface;
22
23 public RestartDialog () {
24 Object (title: "", deletable: false, skip_taskbar_hint: true, skip_pager_hint: true, type_hint: Gdk.WindowTypeHint.DIALOG);
25 }
26
27 construct {
28 try {
29 system_interface = Bus.get_proxy_sync (BusType.SYSTEM, "org.freedesktop.login1", "/org/freedesktop/login1");
30 } catch (IOError e) {
31 stderr.printf ("%s\n", e.message);
32 }
33
34 /*
35 * the restart type is currently used by the indicator for what is
36 * labelled shutdown because of unity's implementation of it
37 * apparently. So we got to adjust to that until they fix this.
38 */
39 string icon_name = "system-shutdown";
40 string heading_text = _("Are you sure you want to Restart?");
41 string content_text = _("This will close all open applications and restart this device.");
42 string button_text = _("Restart");
43
44 set_position (Gtk.WindowPosition.CENTER_ALWAYS);
45 set_keep_above (true);
46 stick ();
47 set_resizable (false);
48
49 var heading = new Gtk.Label ("<span weight='bold' size='larger'>" + heading_text + "</span>");
50 heading.get_style_context ().add_class ("larger");
51 heading.use_markup = true;
52 heading.halign = Gtk.Align.START;
53
54 var grid = new Gtk.Grid ();
55 grid.column_spacing = 12;
56 grid.row_spacing = 12;
57 grid.margin_left = grid.margin_right = grid.margin_bottom = 12;
58 grid.attach (new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DIALOG), 0, 0, 1, 2);
59 grid.attach (heading, 1, 0, 1, 1);
60 grid.attach (new Gtk.Label (content_text), 1, 1, 1, 1);
61
62 var cancel = add_button (_("Cancel"), Gtk.ResponseType.CANCEL) as Gtk.Button;
63 cancel.clicked.connect (() => { destroy (); });
64
65 var confirm = add_button (button_text, Gtk.ResponseType.OK) as Gtk.Button;
66 confirm.get_style_context ().add_class ("destructive-action");
67 confirm.clicked.connect (() => {
68 try {
69 system_interface.reboot (false);
70 } catch (IOError e) {
71 stderr.printf ("%s\n", e.message);
72 }
73
74 destroy ();
75 });
76
77 set_default (confirm);
78
79 get_content_area ().add (grid);
80
81 var action_area = get_action_area ();
82 action_area.margin_right = 6;
83 action_area.margin_bottom = 6;
84 }
85 }
86}
87
088
=== modified file 'src/Widgets/UpdateHeaderRow.vala'
--- src/Widgets/UpdateHeaderRow.vala 2016-09-17 19:28:03 +0000
+++ src/Widgets/UpdateHeaderRow.vala 2017-02-13 23:26:06 +0000
@@ -70,8 +70,8 @@
70 grid.add (widget);70 grid.add (widget);
71 }71 }
7272
73 public void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating) {73 public void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating, bool _restart_required) {
74 grid.update (_update_numbers, _update_real_size, _is_updating);74 grid.update (_update_numbers, _update_real_size, _is_updating, _restart_required);
75 changed (); /* Triggers resort */75 changed (); /* Triggers resort */
76 }76 }
77 /** ---------------- **/77 /** ---------------- **/
@@ -81,19 +81,21 @@
81 public uint update_numbers {get; protected set; default = 0;}81 public uint update_numbers {get; protected set; default = 0;}
82 public uint64 update_real_size {get; protected set; default = 0;}82 public uint64 update_real_size {get; protected set; default = 0;}
83 public bool is_updating {get; protected set; default = false;}83 public bool is_updating {get; protected set; default = false;}
84 public bool restart_required {get; protected set; default = false;}
8485
85 construct {86 construct {
86 margin = 12;87 margin = 12;
87 column_spacing = 12;88 column_spacing = 12;
88 }89 }
8990
90 protected void store_data (uint _update_numbers, uint64 _update_real_size, bool _is_updating) {91 protected void store_data (uint _update_numbers, uint64 _update_real_size, bool _is_updating, bool _restart_required) {
91 update_numbers = _update_numbers;92 update_numbers = _update_numbers;
92 update_real_size = _update_real_size;93 update_real_size = _update_real_size;
93 is_updating = _is_updating;94 is_updating = _is_updating;
95 restart_required = _restart_required;
94 }96 }
9597
96 public abstract void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating);98 public abstract void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating, bool _restart_required);
97 }99 }
98100
99 /** Header to show at top of list if there are updates available **/101 /** Header to show at top of list if there are updates available **/
@@ -114,8 +116,8 @@
114 add (update_size_label);116 add (update_size_label);
115 }117 }
116118
117 public override void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating) {119 public override void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating, bool _restart_required) {
118 store_data (_update_numbers, _update_real_size, _is_updating);120 store_data (_update_numbers, _update_real_size, _is_updating, _restart_required);
119121
120 if (!is_updating) {122 if (!is_updating) {
121 updates_label.label = ngettext ("%u Update Available", "%u Updates Available", update_numbers).printf (update_numbers);123 updates_label.label = ngettext ("%u Update Available", "%u Updates Available", update_numbers).printf (update_numbers);
@@ -147,8 +149,8 @@
147 add (spinner);149 add (spinner);
148 }150 }
149151
150 public override void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating) {152 public override void update (uint _update_numbers, uint64 _update_real_size, bool _is_updating, bool _restart_required) {
151 store_data (_update_numbers, _update_real_size, _is_updating);153 store_data (_update_numbers, _update_real_size, _is_updating, _restart_required);
152154
153 if (is_updating) {155 if (is_updating) {
154 halign = Gtk.Align.CENTER;156 halign = Gtk.Align.CENTER;
@@ -158,11 +160,15 @@
158 label.label = _("Searching for updates…");160 label.label = _("Searching for updates…");
159 label.get_style_context ().remove_class ("h4");161 label.get_style_context ().remove_class ("h4");
160 } else {162 } else {
161 halign = Gtk.Align.START;163 halign = Gtk.Align.FILL;
162 spinner.stop ();164 spinner.stop ();
163 spinner.no_show_all = true;165 spinner.no_show_all = true;
164 spinner.hide ();166 spinner.hide ();
165 label.label = _("Up to Date");167 if (restart_required) {
168 label.label = _("Restart required");
169 } else {
170 label.label = _("Up to Date");
171 }
166 label.get_style_context ().add_class ("h4");172 label.get_style_context ().add_class ("h4");
167 }173 }
168 }174 }

Subscribers

People subscribed via source and target branches