Merge lp:~noskcaj/gnome-settings-daemon/3.14 into lp:~ubuntu-desktop/gnome-settings-daemon/ubuntu

Proposed by Jackson Doak on 2014-12-20
Status: Merged
Merged at revision: 484
Proposed branch: lp:~noskcaj/gnome-settings-daemon/3.14
Merge into: lp:~ubuntu-desktop/gnome-settings-daemon/ubuntu
Diff against target: 23360 lines (+21303/-1301)
82 files modified
debian/changelog (+105/-30)
debian/control (+9/-7)
debian/control.in (+8/-6)
debian/gnome-settings-daemon.install (+0/-1)
debian/patches/01_reinstate_updates_plugin.patch (+4521/-0)
debian/patches/04_superP.patch (+33/-0)
debian/patches/30_xrandr_dbus_init.patch (+65/-0)
debian/patches/43_disable_locale_settings.patch (+7/-6)
debian/patches/53_sync_input_sources_to_accountsservice.patch (+64/-30)
debian/patches/61_revert_libgnomekbd_drop (+0/-1064)
debian/patches/64_restore_terminal_keyboard_shortcut_schema.patch (+21/-12)
debian/patches/geoclue-build-fixes.patch (+0/-78)
debian/patches/nexus-orientation.patch (+21/-25)
debian/patches/revert-gsettings-removals.patch (+26/-30)
debian/patches/series (+3/-2)
debian/patches/ubuntu-lid-close-suspend.patch (+9/-9)
debian/po-up/POTFILES.in (+1/-0)
debian/po-up/ar.po (+272/-0)
debian/po-up/as.po (+244/-0)
debian/po-up/ast.po (+256/-0)
debian/po-up/be.po (+254/-0)
debian/po-up/bg.po (+256/-0)
debian/po-up/bn.po (+251/-0)
debian/po-up/bn_IN.po (+254/-0)
debian/po-up/ca.po (+259/-0)
debian/po-up/ca@valencia.po (+259/-0)
debian/po-up/crh.po (+253/-0)
debian/po-up/cs.po (+269/-0)
debian/po-up/da.po (+277/-0)
debian/po-up/de.po (+274/-0)
debian/po-up/el.po (+286/-0)
debian/po-up/en_GB.po (+252/-0)
debian/po-up/eo.po (+249/-0)
debian/po-up/es.po (+263/-0)
debian/po-up/et.po (+253/-0)
debian/po-up/eu.po (+254/-0)
debian/po-up/fa.po (+266/-0)
debian/po-up/fi.po (+265/-0)
debian/po-up/fr.po (+264/-0)
debian/po-up/gl.po (+263/-0)
debian/po-up/gu.po (+244/-0)
debian/po-up/he.po (+248/-0)
debian/po-up/hi.po (+242/-0)
debian/po-up/hu.po (+257/-0)
debian/po-up/id.po (+249/-0)
debian/po-up/it.po (+266/-0)
debian/po-up/ja.po (+255/-0)
debian/po-up/km.po (+243/-0)
debian/po-up/kn.po (+246/-0)
debian/po-up/ko.po (+243/-0)
debian/po-up/lt.po (+261/-0)
debian/po-up/lv.po (+260/-0)
debian/po-up/mk.po (+264/-0)
debian/po-up/ml.po (+257/-0)
debian/po-up/mr.po (+246/-0)
debian/po-up/nb.po (+248/-0)
debian/po-up/nl.po (+266/-0)
debian/po-up/or.po (+256/-0)
debian/po-up/pa.po (+253/-0)
debian/po-up/patches.pot (+244/-0)
debian/po-up/pl.po (+263/-0)
debian/po-up/pt.po (+251/-0)
debian/po-up/pt_BR.po (+272/-0)
debian/po-up/ro.po (+261/-0)
debian/po-up/ru.po (+265/-0)
debian/po-up/sk.po (+269/-0)
debian/po-up/sl.po (+263/-0)
debian/po-up/sr.po (+264/-0)
debian/po-up/sr@latin.po (+264/-0)
debian/po-up/sv.po (+262/-0)
debian/po-up/ta.po (+260/-0)
debian/po-up/te.po (+252/-0)
debian/po-up/tg.po (+244/-0)
debian/po-up/th.po (+243/-0)
debian/po-up/tr.po (+254/-0)
debian/po-up/ug.po (+241/-0)
debian/po-up/uk.po (+255/-0)
debian/po-up/vi.po (+239/-0)
debian/po-up/zh_CN.po (+254/-0)
debian/po-up/zh_HK.po (+245/-0)
debian/po-up/zh_TW.po (+245/-0)
debian/rules (+3/-1)
To merge this branch: bzr merge lp:~noskcaj/gnome-settings-daemon/3.14
Reviewer Review Type Date Requested Status
Tim Lunn Approve on 2014-12-20
Ubuntu Desktop 2014-12-20 Pending
Review via email: mp+245272@code.launchpad.net

Description of the change

Merge version 3.14 from debian.

To post a comment you must log in.
485. By Jackson Doak on 2014-12-20

Drop ubuntu-force-lock-group.patch, this completely breaks input switching
and the bug that it fixes is no longer reproducible

Tim Lunn (darkxst) wrote :

Thanks Jackson, Looks good.

can confirm no schemas have been removed

Tim Lunn (darkxst) wrote :

Thanks Jackson, looks good.

Can confirm no shared schemas are dropped

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-11-01 13:49:58 +0000
3+++ debian/changelog 2014-12-20 20:23:37 +0000
4@@ -1,3 +1,98 @@
5+gnome-settings-daemon (3.14.2-2ubuntu1) vivid; urgency=low
6+
7+ [ Jackson Doak ]
8+ * Merge with Debian, remaining changes: LP: #1399047
9+ + Split out schemas into gnome-settings-daemon-schemas so
10+ unity-settings-daemon can use them
11+ + debian/patches:
12+ - 05_disable_corner_tapping.patch:
13+ Disable corner tapping when disabling tap to click
14+ - 43_disable_locale_settings.patch:
15+ Don't set locales after sourcing .profile
16+ - 45_suppress-printer-may-not-be-connected-notification.patch
17+ - 53_sync_input_sources_to_accountsservice.patch
18+ - 64_restore_terminal_keyboard_shortcut_schema.patch
19+ - correct_logout_action.patch
20+ display the logout action on ctrl-alt-del (lp: #961501)
21+ - migrate_metacity_keys.patch
22+ Migrate screenshot/terminal keys from metacity gconf as well
23+ (LP: #1058004)
24+ - nexus-orientation.patch
25+ Fix screen rotation on nexus7
26+ - ubuntu-lid-close-suspend.patch
27+ Reimplement support for setting lid close suspend actions
28+ - ubuntu-force-lock-group.patch
29+ Lock the XKB group when ISO_Next_Group is pressed (lp: #1318673)
30+ - revert_background_dropping.patch
31+ Keep gsettings keys background u-s-d needs them
32+ - revert-gsettings-removals.patch
33+ Revert gsettings keys that were dropped since 3.8, for u-s-d
34+ + debian/gnome-settings-daemon.install: Install apport hook
35+ + debian/rules: install upstart scripts
36+ * We now have geoclue-2.0, so drop our revert
37+ * Disable new sharing plugin this requires Network Manager 0.9.10
38+
39+ [ Tim Lunn ]
40+ * Drop ubuntu-force-lock-group.patch, this completely breaks input switching
41+ and the bug that it fixes is no longer reproducible
42+
43+ -- Jackson Doak <noskcaj@ubuntu.com> Fri, 05 Dec 2014 04:09:34 +0000
44+
45+gnome-settings-daemon (3.14.2-2) unstable; urgency=medium
46+
47+ * 01_reinstate_updates_plugin.patch: reinstate the “updates” plugin,
48+ since gnome-software is not in jessie and we need an update
49+ mechanism.
50+ * Use patch-translations.mk.
51+ * Reintroduce GNOME 3.12 translations.
52+ * Update packagekit-glib build-dependency.
53+
54+ -- Josselin Mouette <joss@debian.org> Thu, 04 Dec 2014 10:47:04 +0100
55+
56+gnome-settings-daemon (3.14.2-1) unstable; urgency=medium
57+
58+ * New upstream translation and bugfix release.
59+ * 30_xrandr_dbus_init.patch: patch from upstream git. Fixes a crash
60+ due to a race condition in dbus initialization.
61+
62+ -- Josselin Mouette <joss@debian.org> Sun, 30 Nov 2014 12:46:20 +0100
63+
64+gnome-settings-daemon (3.14.1-1) unstable; urgency=medium
65+
66+ * New upstream release.
67+ * debian/control.in: Bump Standards-Version to 3.9.6 (no further changes)
68+
69+ -- Laurent Bigonville <bigon@debian.org> Sat, 18 Oct 2014 09:47:37 +0200
70+
71+gnome-settings-daemon (3.14.0-2) unstable; urgency=medium
72+
73+ * Do not enable networkmanager support on !linux architectures
74+ * debian/control.in:
75+ - Add libnm-util-dev to the build-dependencies
76+ - Depends against libpam-systemd instead of plain systemd package, g-s-d
77+ needs logind for several power related functionalities
78+
79+ -- Laurent Bigonville <bigon@debian.org> Sun, 05 Oct 2014 04:23:11 +0200
80+
81+gnome-settings-daemon (3.14.0-1) unstable; urgency=medium
82+
83+ * New upstream release.
84+ * debian/gnome-settings-daemon.install: stop installing
85+ usr/share/dbus-1/services. See upstream commit
86+ "keyboard: Remove input sources handling".
87+ * Bump Breaks on gnome-shell to 3.13.92 because of the above.
88+ * Upload to unstable.
89+
90+ -- Andreas Henriksson <andreas@fatal.se> Mon, 22 Sep 2014 20:05:46 +0200
91+
92+gnome-settings-daemon (3.13.91-1) experimental; urgency=medium
93+
94+ * New upstream development release.
95+ * Update build-dependencies according to configure.ac changes:
96+ - Add libnm-glib-dev (>= 0.9.9.1)
97+
98+ -- Andreas Henriksson <andreas@fatal.se> Fri, 05 Sep 2014 15:00:51 -0700
99+
100 gnome-settings-daemon (3.12.2-1ubuntu4) vivid; urgency=medium
101
102 * geoclue-2.0 build-deps were accidentally uncommented in the previous
103@@ -572,6 +667,7 @@
104 * New upstream release
105
106 -- Sjoerd Simons <sjoerd@debian.org> Fri, 15 Feb 2013 22:12:34 +0100
107+
108 gnome-settings-daemon (3.6.4-0ubuntu19) saucy; urgency=low
109
110 * Install the ibus dbus service (LP: #1194138)
111@@ -1417,6 +1513,7 @@
112 otherwise the build will fail with unresolved symbol *errors*
113
114 -- Sjoerd Simons <sjoerd@debian.org> Sun, 13 Nov 2011 16:25:33 +0100
115+
116 gnome-settings-daemon (3.2.2-0ubuntu17) precise; urgency=low
117
118 * debian/patches/disable_three_touch_tap.patch
119@@ -1587,7 +1684,6 @@
120
121 -- Sjoerd Simons <sjoerd@debian.org> Wed, 26 Oct 2011 14:01:21 +0200
122
123-
124 gnome-settings-daemon (3.2.1-0ubuntu3) oneiric-proposed; urgency=low
125
126 * debian/patches/00git_remove_assertions.patch:
127@@ -2069,34 +2165,15 @@
128 [ Guido Günther ]
129 * Bump build-dependency on libgnome-desktop-3-dev (Closes: #622689)
130
131- [ Rodrigo Moya ]
132- * Rebase from Debian, remaining Ubuntu changes:
133- * debian/control:
134- - Build-depend on libnotify4-dev, not libnotify-dev
135- - Add Buil-depend on libappindicator3-dev
136- - Add Vcs-Bzr URL
137- * debian/gnome-settings-daemon.install:
138- * debian/gnome-settings-daemon.postinst:
139- - Keep autostart files in standard directories
140- * debian/gnome-update-wallpaper-cache.c:
141- * debian/rules:
142- - Add wallpaper cache updater program
143- * debian/patches/02_missing_libs.patch:
144- - Add missing X11 libraries to build dependencies
145- * debian/patches/05_disable_corner_tapping.patch:
146- - Disable corner tapping when disabling tap to click
147- * debian/patches/06_use_application_indicator.patch:
148- - Use application indicators
149- * debian/patches/16_use_synchronous_notifications.patch:
150- - Use synchronous notifications when they are supported
151- * debian/patches/17_react_when_streams_removed.patch:
152- - React to stream-removed signal from GvcMixerControl
153- * debian/patches/40_xres_lcddefault.patch:
154- - OpenOffice.org subpixel font rendering broken with new cairo
155- * debian/gnome-settings-daemon.gconf-defaults:
156- - Needs to be moved to GSettings
157+ [ Josselin Mouette ]
158+ * Break gdm3 < version with GSettings support.
159+ * New upstream release.
160+ * 01_numlock.patch: new patch. Work around the lack of support for
161+ per-host NumLock status by providing at least a global setting. It
162+ can turn wrong in multi-host environments, but it’s better than
163+ nothing in the general case.
164
165- -- Rodrigo Moya <rodrigo.moya@canonical.com> Wed, 04 May 2011 13:07:16 +0200
166+ -- Josselin Mouette <joss@debian.org> Sat, 04 Jun 2011 18:33:11 +0200
167
168 gnome-settings-daemon (3.0.1-1ubuntu4) oneiric; urgency=low
169
170@@ -2151,8 +2228,6 @@
171
172 -- Rodrigo Moya <rodrigo.moya@canonical.com> Mon, 09 May 2011 11:24:49 +0200
173
174-gnome-settings-daemon (3.0.0.1-1ubuntu1) oneiric; urgency=low
175-
176 gnome-settings-daemon (3.0.0.1-1) experimental; urgency=low
177
178 * New upstream release.
179
180=== modified file 'debian/control'
181--- debian/control 2014-11-01 13:49:49 +0000
182+++ debian/control 2014-12-20 20:23:37 +0000
183@@ -7,7 +7,7 @@
184 Priority: optional
185 Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>
186 XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
187-Uploaders: Andreas Henriksson <andreas@fatal.se>, Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>, Emilio Pozuelo Monfort <pochu@debian.org>
188+Uploaders: Andreas Henriksson <andreas@fatal.se>, Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>, Josselin Mouette <joss@debian.org>, Laurent Bigonville <bigon@debian.org>
189 Build-Depends: cdbs,
190 debhelper (>= 9),
191 gnome-pkg-tools,
192@@ -18,6 +18,8 @@
193 libaccountsservice-dev (>= 0.6.34),
194 libglib2.0-dev (>= 2.37.7),
195 libgtk-3-dev (>= 3.7.8),
196+ libnm-glib-dev (>= 0.9.8) [linux-any],
197+ libnm-util-dev (>= 0.9.8) [linux-any],
198 libnotify-dev (>= 0.7.3),
199 libxt-dev,
200 libxi-dev,
201@@ -32,7 +34,7 @@
202 libcanberra-gtk3-dev,
203 libcups2-dev,
204 libpolkit-gobject-1-dev,
205- libpackagekit-glib2-dev (>= 0.6.4),
206+ libpackagekit-glib2-dev (>= 0.8.1),
207 libupower-glib-dev (>= 0.99.0),
208 libgudev-1.0-dev [linux-any],
209 libcolord-dev (>= 1.0.2),
210@@ -42,18 +44,18 @@
211 xserver-xorg-input-wacom [!hurd-any !kfreebsd-any !s390 !s390x],
212 librsvg2-dev (>= 2.36.2),
213 libgweather-3-dev (>= 3.9.5),
214-# libgeocode-glib-dev (>= 3.10.0),
215-# geoclue-2.0 (>= 2.1.2),
216+ libgeocode-glib-dev (>= 3.10.0),
217+ geoclue-2.0 (>= 2.1.2),
218 xkb-data,
219 libxkbfile-dev,
220-Standards-Version: 3.9.5
221+Standards-Version: 3.9.6
222 Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/gnome-settings-daemon/ubuntu
223
224 Package: gnome-settings-daemon
225 Architecture: any
226 Depends: ${shlibs:Depends},
227 ${misc:Depends},
228- systemd [!hurd-any !kfreebsd-any],
229+ libpam-systemd [!hurd-any !kfreebsd-any],
230 gsettings-desktop-schemas (>= 3.10.0),
231 nautilus-data (>= 2.91.3-1),
232 gnome-settings-daemon-schemas (= ${source:Version})
233@@ -63,7 +65,7 @@
234 Breaks: gnome-session (<< 2.24),
235 gnome-screensaver (<< 2.28.0),
236 gnome-color-manager (<< 3.0),
237- gnome-shell ( << 3.7),
238+ gnome-shell ( << 3.13.92),
239 gnome-control-center ( << 3.7),
240 gdm (<< 3.0)
241 Suggests: x11-xserver-utils,
242
243=== modified file 'debian/control.in'
244--- debian/control.in 2014-10-31 10:08:27 +0000
245+++ debian/control.in 2014-12-20 20:23:37 +0000
246@@ -14,6 +14,8 @@
247 libaccountsservice-dev (>= 0.6.34),
248 libglib2.0-dev (>= 2.37.7),
249 libgtk-3-dev (>= 3.7.8),
250+ libnm-glib-dev (>= 0.9.8) [linux-any],
251+ libnm-util-dev (>= 0.9.8) [linux-any],
252 libnotify-dev (>= 0.7.3),
253 libxt-dev,
254 libxi-dev,
255@@ -28,7 +30,7 @@
256 libcanberra-gtk3-dev,
257 libcups2-dev,
258 libpolkit-gobject-1-dev,
259- libpackagekit-glib2-dev (>= 0.6.4),
260+ libpackagekit-glib2-dev (>= 0.8.1),
261 libupower-glib-dev (>= 0.99.0),
262 libgudev-1.0-dev [linux-any],
263 libcolord-dev (>= 1.0.2),
264@@ -38,18 +40,18 @@
265 xserver-xorg-input-wacom [!hurd-any !kfreebsd-any !s390 !s390x],
266 librsvg2-dev (>= 2.36.2),
267 libgweather-3-dev (>= 3.9.5),
268-# libgeocode-glib-dev (>= 3.10.0),
269-# geoclue-2.0 (>= 2.1.2),
270+ libgeocode-glib-dev (>= 3.10.0),
271+ geoclue-2.0 (>= 2.1.2),
272 xkb-data,
273 libxkbfile-dev,
274-Standards-Version: 3.9.5
275+Standards-Version: 3.9.6
276 Vcs-Bzr: https://code.launchpad.net/~ubuntu-desktop/gnome-settings-daemon/ubuntu
277
278 Package: gnome-settings-daemon
279 Architecture: any
280 Depends: ${shlibs:Depends},
281 ${misc:Depends},
282- systemd [!hurd-any !kfreebsd-any],
283+ libpam-systemd [!hurd-any !kfreebsd-any],
284 gsettings-desktop-schemas (>= 3.10.0),
285 nautilus-data (>= 2.91.3-1),
286 gnome-settings-daemon-schemas (= ${source:Version})
287@@ -59,7 +61,7 @@
288 Breaks: gnome-session (<< 2.24),
289 gnome-screensaver (<< 2.28.0),
290 gnome-color-manager (<< 3.0),
291- gnome-shell ( << 3.7),
292+ gnome-shell ( << 3.13.92),
293 gnome-control-center ( << 3.7),
294 gdm (<< 3.0)
295 Suggests: x11-xserver-utils,
296
297=== modified file 'debian/gnome-settings-daemon.install'
298--- debian/gnome-settings-daemon.install 2014-09-23 23:33:37 +0000
299+++ debian/gnome-settings-daemon.install 2014-12-20 20:23:37 +0000
300@@ -1,6 +1,5 @@
301 etc/xdg/autostart
302 usr/lib/gnome-settings-daemon*
303-usr/share/dbus-1/services
304 usr/share/icons
305 usr/share/locale
306 usr/share/gnome-settings-daemon*
307
308=== added file 'debian/patches/01_reinstate_updates_plugin.patch'
309--- debian/patches/01_reinstate_updates_plugin.patch 1970-01-01 00:00:00 +0000
310+++ debian/patches/01_reinstate_updates_plugin.patch 2014-12-20 20:23:37 +0000
311@@ -0,0 +1,4521 @@
312+Index: gnome-settings-daemon-3.14.2/configure.ac
313+===================================================================
314+--- gnome-settings-daemon-3.14.2.orig/configure.ac 2014-12-02 00:06:35.445485473 +0100
315++++ gnome-settings-daemon-3.14.2/configure.ac 2014-12-02 00:06:35.437485592 +0100
316+@@ -291,6 +291,33 @@ esac
317+ AM_CONDITIONAL(HAVE_WACOM, test x$have_wacom = xyes)
318+
319+ dnl ==============================================
320++dnl PackageKit section
321++dnl ==============================================
322++
323++have_packagekit=false
324++AC_ARG_ENABLE(packagekit,
325++ AC_HELP_STRING([--disable-packagekit],
326++ [turn off PackageKit support]),
327++ [case "${enableval}" in
328++ yes) WANT_PACKAGEKIT=yes ;;
329++ no) WANT_PACKAGEKIT=no ;;
330++ *) AC_MSG_ERROR(bad value ${enableval} for --disable-packagekit) ;;
331++ esac],
332++ [WANT_PACKAGEKIT=yes]) dnl Default value
333++
334++if test x$WANT_PACKAGEKIT = xyes ; then
335++ PK_REQUIRED_VERSION=0.8.1
336++ PKG_CHECK_MODULES(PACKAGEKIT, glib-2.0 packagekit-glib2 >= $PK_REQUIRED_VERSION upower-glib >= $UPOWER_REQUIRED_VERSION gudev-1.0 libnotify >= $LIBNOTIFY_REQUIRED_VERSION,
337++ [have_packagekit=true
338++ AC_DEFINE(HAVE_PACKAGEKIT, 1, [Define if PackageKit should be used])],
339++ [have_packagekit=false])
340++fi
341++AM_CONDITIONAL(HAVE_PACKAGEKIT, test "x$have_packagekit" = "xtrue")
342++
343++AC_SUBST(PACKAGEKIT_CFLAGS)
344++AC_SUBST(PACKAGEKIT_LIBS)
345++
346++dnl ==============================================
347+ dnl smartcard section
348+ dnl ==============================================
349+ have_smartcard_support=false
350+@@ -537,6 +564,7 @@ plugins/screensaver-proxy/Makefile
351+ plugins/sharing/Makefile
352+ plugins/smartcard/Makefile
353+ plugins/sound/Makefile
354++plugins/updates/Makefile
355+ plugins/wacom/Makefile
356+ plugins/xrandr/Makefile
357+ plugins/xsettings/Makefile
358+@@ -554,6 +582,7 @@ data/org.gnome.settings-daemon.periphera
359+ data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in
360+ data/org.gnome.settings-daemon.plugins.orientation.gschema.xml.in
361+ data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in
362++data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in
363+ data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in
364+ data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in
365+ data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in
366+@@ -588,6 +617,7 @@ echo "
367+ LCMS DICT support: ${have_new_lcms}
368+ NetworkManager support: ${enable_network_manager}
369+ Libnotify support: ${have_libnotify}
370++ PackageKit support: ${have_packagekit}
371+ Smartcard support: ${have_smartcard_support}
372+ Cups support: ${enable_cups}
373+ Wacom support: ${have_wacom}
374+Index: gnome-settings-daemon-3.14.2/data/Makefile.am
375+===================================================================
376+--- gnome-settings-daemon-3.14.2.orig/data/Makefile.am 2014-12-02 00:06:35.445485473 +0100
377++++ gnome-settings-daemon-3.14.2/data/Makefile.am 2014-12-02 00:06:35.437485592 +0100
378+@@ -19,6 +19,7 @@ gsettings_SCHEMAS = \
379+ org.gnome.settings-daemon.plugins.housekeeping.gschema.xml \
380+ org.gnome.settings-daemon.plugins.print-notifications.gschema.xml \
381+ org.gnome.settings-daemon.plugins.xrandr.gschema.xml \
382++ org.gnome.settings-daemon.plugins.updates.gschema.xml \
383+ org.gnome.settings-daemon.plugins.orientation.gschema.xml \
384+ org.gnome.settings-daemon.peripherals.wacom.gschema.xml
385+
386+Index: gnome-settings-daemon-3.14.2/data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in
387+===================================================================
388+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
389++++ gnome-settings-daemon-3.14.2/data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in 2014-12-02 00:06:35.437485592 +0100
390+@@ -0,0 +1,79 @@
391++<schemalist>
392++ <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.updates" path="/org/gnome/settings-daemon/plugins/updates/">
393++ <key name="active" type="b">
394++ <default>true</default>
395++ <_summary>Activation of this plugin</_summary>
396++ <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
397++ </key>
398++ <key name="priority" type="i">
399++ <default>0</default>
400++ <_summary>Priority to use for this plugin</_summary>
401++ <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
402++ </key>
403++ <key name="connection-use-mobile" type="b">
404++ <default>false</default>
405++ <_summary>Use mobile broadband connections</_summary>
406++ <_description>Use mobile broadband connections such as GSM and CDMA to check for updates.</_description>
407++ </key>
408++ <key name="auto-download-updates" type="b">
409++ <default>true</default>
410++ <_summary>Automatically download updates in the background without confirmation</_summary>
411++ <_description>Automatically download updates in the background without confirmation. Updates will be auto-downloaded when using wired network connnections, and mobile broadband if 'connection-use-mobile' is enabled.</_description>
412++ </key>
413++ <key name="frequency-get-updates" type="i">
414++ <default>86400</default>
415++ <_summary>How often to check for updates</_summary>
416++ <_description>How often to check for updates. Value is in seconds. This is a maximum amount of time that can pass between a security update being published, and the update being automatically installed or the user notified.</_description>
417++ </key>
418++ <key name="frequency-updates-notification" type="i">
419++ <default>604800</default>
420++ <_summary>How often to notify the user that non-critical updates are available</_summary>
421++ <_description>How often to tell the user there are non-critical updates. Value is in seconds. Security update notifications are always shown after the check for updates, but non-critical notifications should be shown a lot less frequently.</_description>
422++ </key>
423++ <key name="last-updates-notification" type="t">
424++ <default>0</default>
425++ <_summary>The last time we told the user about non-critical notifications</_summary>
426++ <_description>The last time we notified the user about non-critical updates. Value is in seconds since the epoch, or zero for never.</_description>
427++ </key>
428++ <key name="frequency-get-upgrades" type="i">
429++ <default>604800</default>
430++ <_summary>How often to check for distribution upgrades</_summary>
431++ <_description>How often to check for distribution upgrades. Value is in seconds.</_description>
432++ </key>
433++ <key name="frequency-refresh-cache" type="i">
434++ <default>86400</default>
435++ <_summary>How often to refresh the package cache</_summary>
436++ <_description>How often to refresh the package cache. Value is in seconds.</_description>
437++ </key>
438++ <key name="update-battery" type="b">
439++ <default>false</default>
440++ <_summary>Check for updates when running on battery power</_summary>
441++ <_description>Check for updates when running on battery power.</_description>
442++ </key>
443++ <key name="notify-distro-upgrades" type="b">
444++ <default>false</default>
445++ <_summary>Notify the user when distribution upgrades are available</_summary>
446++ <_description>Notify the user when distribution upgrades are available.</_description>
447++ </key>
448++ <key name="enable-check-firmware" type="b">
449++ <default>true</default>
450++ <_summary>Ask the user if additional firmware should be installed</_summary>
451++ <_description>Ask the user if additional firmware should be installed if it is available.</_description>
452++ </key>
453++ <key name="banned-firmware" type="s">
454++ <default>'*/intel-ucode/*'</default>
455++ <_summary>Firmware files that should not be searched for</_summary>
456++ <_description>Firmware files that should not be searched for, separated by commas. These can include '*' and '?' characters.</_description>
457++ </key>
458++ <key name="ignored-devices" type="s">
459++ <default>''</default>
460++ <_summary>Devices that should be ignored</_summary>
461++ <_description>Devices that should be ignored, separated by commas. These can include '*' and '?' characters.</_description>
462++ </key>
463++ <key name="media-repo-filenames" type="s">
464++ <default>'media.repo,.discinfo'</default>
465++ <_summary>The filenames on removable media that designate it a software source.</_summary>
466++ <_description>When removable media is inserted, it is checked to see if it contains any important filenames in the root directory. If the filename matches, then an updates check is performed. This allows post-install disks to be used to update running systems.</_description>
467++ </key>
468++ </schema>
469++</schemalist>
470+Index: gnome-settings-daemon-3.14.2/plugins/Makefile.am
471+===================================================================
472+--- gnome-settings-daemon-3.14.2.orig/plugins/Makefile.am 2014-12-02 00:06:35.445485473 +0100
473++++ gnome-settings-daemon-3.14.2/plugins/Makefile.am 2014-12-02 00:06:35.437485592 +0100
474+@@ -22,6 +22,12 @@ enabled_plugins = \
475+
476+ disabled_plugins = $(NULL)
477+
478++if HAVE_PACKAGEKIT
479++enabled_plugins += updates
480++else
481++disabled_plugins += updates
482++endif
483++
484+ if SMARTCARD_SUPPORT
485+ enabled_plugins += smartcard
486+ else
487+Index: gnome-settings-daemon-3.14.2/plugins/updates/Makefile.am
488+===================================================================
489+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
490++++ gnome-settings-daemon-3.14.2/plugins/updates/Makefile.am 2014-12-02 00:06:35.437485592 +0100
491+@@ -0,0 +1,93 @@
492++plugin_name = updates
493++
494++plugin_LTLIBRARIES = \
495++ libupdates.la
496++
497++libupdates_la_SOURCES = \
498++ gsd-updates-common.h \
499++ gsd-updates-plugin.c \
500++ gsd-updates-refresh.h \
501++ gsd-updates-refresh.c \
502++ gsd-updates-firmware.h \
503++ gsd-updates-firmware.c \
504++ gsd-updates-manager.h \
505++ gsd-updates-manager.c
506++
507++libupdates_la_CPPFLAGS = \
508++ -I$(top_srcdir)/gnome-settings-daemon \
509++ -I$(top_builddir)/gnome-settings-daemon \
510++ -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
511++ $(AM_CPPFLAGS)
512++
513++libupdates_la_CFLAGS = \
514++ $(PLUGIN_CFLAGS) \
515++ $(SETTINGS_PLUGIN_CFLAGS) \
516++ $(GUDEV_CFLAGS) \
517++ -DG_UDEV_API_IS_SUBJECT_TO_CHANGE \
518++ $(PACKAGEKIT_CFLAGS) \
519++ -DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE \
520++ -DDATADIR=\"$(datadir)\" \
521++ -DBINDIR=\"$(bindir)\" \
522++ -DLIBEXECDIR=\"$(libexecdir)\" \
523++ -I$(top_srcdir)/data \
524++ $(AM_CFLAGS)
525++
526++libupdates_la_LDFLAGS = \
527++ $(GSD_PLUGIN_LDFLAGS)
528++
529++libupdates_la_LIBADD = \
530++ $(SETTINGS_PLUGIN_LIBS) \
531++ $(PACKAGEKIT_LIBS)
532++
533++plugin_in_files = \
534++ updates.gnome-settings-plugin.in
535++
536++plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
537++
538++libexec_PROGRAMS = gsd-test-updates
539++
540++gsd_test_updates_SOURCES = \
541++ test-updates.c \
542++ gsd-updates-common.h \
543++ gsd-updates-refresh.h \
544++ gsd-updates-refresh.c \
545++ gsd-updates-firmware.h \
546++ gsd-updates-firmware.c \
547++ gsd-updates-manager.h \
548++ gsd-updates-manager.c
549++
550++gsd_test_updates_CPPFLAGS = \
551++ -I$(top_srcdir)/data/ \
552++ -I$(top_srcdir)/gnome-settings-daemon \
553++ -I$(top_builddir)/gnome-settings-daemon \
554++ -I$(top_srcdir)/plugins/common \
555++ -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \
556++ -DLIBEXECDIR=\""$(libexecdir)"\" \
557++ $(AM_CPPFLAGS)
558++
559++gsd_test_updates_CFLAGS = \
560++ -DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE \
561++ -DDATADIR=\"$(datadir)\" \
562++ -DBINDIR=\"$(bindir)\" \
563++ $(PLUGIN_CFLAGS) \
564++ $(SETTINGS_PLUGIN_CFLAGS) \
565++ $(PACKAGEKIT_CFLAGS) \
566++ $(AM_CFLAGS)
567++
568++gsd_test_updates_LDADD = \
569++ $(top_builddir)/gnome-settings-daemon/libgsd.la \
570++ $(SETTINGS_DAEMON_LIBS) \
571++ $(SETTINGS_PLUGIN_LIBS) \
572++ $(PACKAGEKIT_LIBS) \
573++ -lm
574++
575++EXTRA_DIST = \
576++ $(plugin_in_files)
577++
578++CLEANFILES = \
579++ $(plugin_DATA)
580++
581++DISTCLEANFILES = \
582++ $(plugin_DATA)
583++
584++@GSD_INTLTOOL_PLUGIN_RULE@
585+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-common.h
586+===================================================================
587+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
588++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-common.h 2014-12-02 00:06:35.437485592 +0100
589+@@ -0,0 +1,44 @@
590++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
591++ *
592++ * Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
593++ *
594++ * Licensed under the GNU General Public License Version 2
595++ *
596++ * This program is free software; you can redistribute it and/or modify
597++ * it under the terms of the GNU General Public License as published by
598++ * the Free Software Foundation; either version 2 of the License, or
599++ * (at your option) any later version.
600++ *
601++ * This program is distributed in the hope that it will be useful,
602++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
603++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
604++ * GNU General Public License for more details.
605++ *
606++ * You should have received a copy of the GNU General Public License
607++ * along with this program; if not, write to the Free Software
608++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
609++ */
610++
611++#ifndef __GSD_UPDATES_COMMON_H
612++#define __GSD_UPDATES_COMMON_H
613++
614++G_BEGIN_DECLS
615++
616++#define GSD_SETTINGS_BANNED_FIRMWARE "banned-firmware"
617++#define GSD_SETTINGS_CONNECTION_USE_MOBILE "connection-use-mobile"
618++#define GSD_SETTINGS_ENABLE_CHECK_FIRMWARE "enable-check-firmware"
619++#define GSD_SETTINGS_FREQUENCY_GET_UPDATES "frequency-get-updates"
620++#define GSD_SETTINGS_FREQUENCY_GET_UPGRADES "frequency-get-upgrades"
621++#define GSD_SETTINGS_FREQUENCY_REFRESH_CACHE "frequency-refresh-cache"
622++#define GSD_SETTINGS_FREQUENCY_UPDATES_NOTIFICATION "frequency-updates-notification"
623++#define GSD_SETTINGS_IGNORED_DEVICES "ignored-devices"
624++#define GSD_SETTINGS_LAST_UPDATES_NOTIFICATION "last-updates-notification"
625++#define GSD_SETTINGS_MEDIA_REPO_FILENAMES "media-repo-filenames"
626++#define GSD_SETTINGS_NOTIFY_DISTRO_UPGRADES "notify-distro-upgrades"
627++#define GSD_SETTINGS_SCHEMA "org.gnome.settings-daemon.plugins.updates"
628++#define GSD_SETTINGS_UPDATE_BATTERY "update-battery"
629++#define GSD_SETTINGS_AUTO_DOWNLOAD_UPDATES "auto-download-updates"
630++
631++G_END_DECLS
632++
633++#endif /* __GSD_UPDATES_COMMON_H */
634+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-firmware.c
635+===================================================================
636+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
637++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-firmware.c 2014-12-02 00:06:35.437485592 +0100
638+@@ -0,0 +1,1040 @@
639++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
640++ *
641++ * Copyright (C) 2007-2012 Richard Hughes <richard@hughsie.com>
642++ *
643++ * Licensed under the GNU General Public License Version 2
644++ *
645++ * This program is free software; you can redistribute it and/or modify
646++ * it under the terms of the GNU General Public License as published by
647++ * the Free Software Foundation; either version 2 of the License, or
648++ * (at your option) any later version.
649++ *
650++ * This program is distributed in the hope that it will be useful,
651++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
652++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
653++ * GNU General Public License for more details.
654++ *
655++ * You should have received a copy of the GNU General Public License
656++ * along with this program; if not, write to the Free Software
657++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
658++ */
659++
660++#include "config.h"
661++
662++#include <stdlib.h>
663++#include <string.h>
664++#include <stdio.h>
665++#include <time.h>
666++#include <errno.h>
667++
668++#include <string.h>
669++#include <sys/time.h>
670++#include <sys/types.h>
671++#ifdef HAVE_UNISTD_H
672++#include <unistd.h>
673++#endif /* HAVE_UNISTD_H */
674++#include <glib/gi18n.h>
675++#include <gio/gio.h>
676++#include <libnotify/notify.h>
677++#include <packagekit-glib2/packagekit.h>
678++#ifdef HAVE_GUDEV
679++#include <gudev/gudev.h>
680++#endif
681++
682++#include "gsd-updates-common.h"
683++#include "gsd-updates-firmware.h"
684++
685++static void gsd_updates_firmware_finalize (GObject *object);
686++
687++#define GSD_UPDATES_FIRMWARE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_UPDATES_TYPE_FIRMWARE, GsdUpdatesFirmwarePrivate))
688++#define GSD_UPDATES_FIRMWARE_MISSING_DIR "/run/udev/firmware-missing"
689++#define GSD_UPDATES_FIRMWARE_LOADING_DIR "/lib/firmware"
690++#define GSD_UPDATES_FIRMWARE_LOGIN_DELAY 10 /* seconds */
691++#define GSD_UPDATES_FIRMWARE_PROCESS_DELAY 2 /* seconds */
692++#define GSD_UPDATES_FIRMWARE_INSERT_DELAY 2 /* seconds */
693++#define GSD_UPDATES_FIRMWARE_DEVICE_REBIND_PROGRAM "/usr/sbin/pk-device-rebind"
694++
695++struct GsdUpdatesFirmwarePrivate
696++{
697++ GSettings *settings;
698++ GFileMonitor *monitor;
699++ GPtrArray *array_requested;
700++ PkTask *task;
701++ GPtrArray *packages_found;
702++ guint timeout_id;
703++};
704++
705++typedef enum {
706++ FIRMWARE_SUBSYSTEM_USB,
707++ FIRMWARE_SUBSYSTEM_PCI,
708++ FIRMWARE_SUBSYSTEM_UNKNOWN
709++} FirmwareSubsystem;
710++
711++typedef struct {
712++ gchar *filename;
713++ gchar *sysfs_path;
714++ gchar *model;
715++ gchar *id;
716++ FirmwareSubsystem subsystem;
717++} GsdUpdatesFirmwareRequest;
718++
719++G_DEFINE_TYPE (GsdUpdatesFirmware, gsd_updates_firmware, G_TYPE_OBJECT)
720++
721++static void install_package_ids (GsdUpdatesFirmware *firmware);
722++static void ignore_devices (GsdUpdatesFirmware *firmware);
723++
724++static gboolean
725++subsystem_can_replug (FirmwareSubsystem subsystem)
726++{
727++ if (subsystem == FIRMWARE_SUBSYSTEM_USB)
728++ return TRUE;
729++ return FALSE;
730++}
731++
732++static GsdUpdatesFirmwareRequest *
733++request_new (const gchar *filename, const gchar *sysfs_path)
734++{
735++ GsdUpdatesFirmwareRequest *req;
736++#ifdef HAVE_GUDEV
737++ GUdevDevice *device;
738++ GUdevClient *client;
739++ const gchar *subsystem;
740++ const gchar *model;
741++ const gchar *id_vendor;
742++ const gchar *id_product;
743++#endif
744++
745++ req = g_new0 (GsdUpdatesFirmwareRequest, 1);
746++ req->filename = g_strdup (filename);
747++ req->sysfs_path = g_strdup (sysfs_path);
748++ req->subsystem = FIRMWARE_SUBSYSTEM_UNKNOWN;
749++#ifdef HAVE_GUDEV
750++
751++ /* get all subsystems */
752++ client = g_udev_client_new (NULL);
753++ device = g_udev_client_query_by_sysfs_path (client, sysfs_path);
754++ if (device == NULL)
755++ goto out;
756++
757++ /* find subsystem, which will affect if we have to replug, or reboot */
758++ subsystem = g_udev_device_get_subsystem (device);
759++ if (g_strcmp0 (subsystem, "usb") == 0) {
760++ req->subsystem = FIRMWARE_SUBSYSTEM_USB;
761++ } else if (g_strcmp0 (subsystem, "pci") == 0) {
762++ req->subsystem = FIRMWARE_SUBSYSTEM_PCI;
763++ } else {
764++ g_warning ("subsystem unrecognised: %s", subsystem);
765++ }
766++
767++ /* get model, so we can show something sensible */
768++ model = g_udev_device_get_property (device, "ID_MODEL");
769++ if (model != NULL && model[0] != '\0') {
770++ req->model = g_strdup (model);
771++ /* replace invalid chars */
772++ g_strdelimit (req->model, "_", ' ');
773++ }
774++
775++ /* create ID so we can ignore the specific device */
776++ id_vendor = g_udev_device_get_property (device, "ID_VENDOR");
777++ id_product = g_udev_device_get_property (device, "ID_MODEL_ID");
778++ req->id = g_strdup_printf ("%s_%s", id_vendor, id_product);
779++out:
780++ if (device != NULL)
781++ g_object_unref (device);
782++ g_object_unref (client);
783++#endif
784++ return req;
785++}
786++
787++static void
788++request_free (GsdUpdatesFirmwareRequest *req)
789++{
790++ g_free (req->filename);
791++ g_free (req->model);
792++ g_free (req->sysfs_path);
793++ g_free (req->id);
794++ g_free (req);
795++}
796++
797++static gboolean
798++device_rebind (GsdUpdatesFirmware *firmware)
799++{
800++ gboolean ret;
801++ gchar *argv[4];
802++ gchar *rebind_stderr = NULL;
803++ gchar *rebind_stdout = NULL;
804++ GError *error = NULL;
805++ gint exit_status = 0;
806++ guint i;
807++ GPtrArray *array;
808++ const GsdUpdatesFirmwareRequest *req;
809++ GString *string;
810++
811++ string = g_string_new ("");
812++
813++ /* make a string array of all the devices to replug */
814++ array = firmware->priv->array_requested;
815++ for (i=0; i<array->len; i++) {
816++ req = g_ptr_array_index (array, i);
817++ g_string_append_printf (string, "%s ", req->sysfs_path);
818++ }
819++
820++ /* remove trailing space */
821++ if (string->len > 0)
822++ g_string_set_size (string, string->len-1);
823++
824++ /* use PolicyKit to do this as root */
825++ argv[0] = "pkexec";
826++ argv[1] = GSD_UPDATES_FIRMWARE_DEVICE_REBIND_PROGRAM;
827++ argv[2] = string->str;
828++ argv[3] = NULL;
829++ ret = g_spawn_sync (NULL,
830++ argv,
831++ NULL,
832++ G_SPAWN_SEARCH_PATH,
833++ NULL, NULL,
834++ &rebind_stdout,
835++ &rebind_stderr,
836++ &exit_status,
837++ &error);
838++ if (!ret) {
839++ g_warning ("failed to spawn '%s': %s",
840++ argv[1], error->message);
841++ g_error_free (error);
842++ goto out;
843++ }
844++
845++ /* if we failed to rebind the device */
846++ if (exit_status != 0) {
847++ g_warning ("failed to rebind: %s, %s",
848++ rebind_stdout, rebind_stderr);
849++ ret = FALSE;
850++ goto out;
851++ }
852++out:
853++ g_free (rebind_stdout);
854++ g_free (rebind_stderr);
855++ g_string_free (string, TRUE);
856++ return ret;
857++}
858++static void
859++libnotify_cb (NotifyNotification *notification, gchar *action, gpointer data)
860++{
861++ GsdUpdatesFirmware *firmware = GSD_UPDATES_FIRMWARE (data);
862++
863++ if (g_strcmp0 (action, "install-firmware") == 0) {
864++ install_package_ids (firmware);
865++ } else if (g_strcmp0 (action, "ignore-devices") == 0) {
866++ ignore_devices (firmware);
867++ } else {
868++ g_warning ("unknown action id: %s", action);
869++ }
870++ notify_notification_close (notification, NULL);
871++}
872++
873++static void
874++on_notification_closed (NotifyNotification *notification, gpointer data)
875++{
876++ g_object_unref (notification);
877++}
878++
879++static void
880++require_restart (GsdUpdatesFirmware *firmware)
881++{
882++ const gchar *message;
883++ gboolean ret;
884++ GError *error = NULL;
885++ NotifyNotification *notification;
886++
887++ /* TRANSLATORS: we need to restart so the new hardware can re-request the firmware */
888++ message = _("You will need to restart this computer before the hardware will work correctly.");
889++
890++ /* TRANSLATORS: title of libnotify bubble */
891++ notification = notify_notification_new (_("Additional software was installed"), message, NULL);
892++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
893++ notify_notification_set_app_name (notification, _("Software Updates"));
894++ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
895++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
896++ g_signal_connect (notification, "closed",
897++ G_CALLBACK (on_notification_closed), NULL);
898++
899++ /* show the bubble */
900++ ret = notify_notification_show (notification, &error);
901++ if (!ret) {
902++ g_warning ("error: %s", error->message);
903++ g_error_free (error);
904++ }
905++}
906++
907++static void
908++require_replug (GsdUpdatesFirmware *firmware)
909++{
910++ const gchar *message;
911++ gboolean ret;
912++ GError *error = NULL;
913++ NotifyNotification *notification;
914++
915++ /* TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware */
916++ message = _("You will need to remove and then reinsert the hardware before it will work correctly.");
917++
918++ /* TRANSLATORS: title of libnotify bubble */
919++ notification = notify_notification_new (_("Additional software was installed"), message, NULL);
920++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
921++ notify_notification_set_app_name (notification, _("Software Updates"));
922++ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
923++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
924++ g_signal_connect (notification, "closed",
925++ G_CALLBACK (on_notification_closed), NULL);
926++
927++ /* show the bubble */
928++ ret = notify_notification_show (notification, &error);
929++ if (!ret) {
930++ g_warning ("error: %s", error->message);
931++ g_error_free (error);
932++ }
933++}
934++
935++static void
936++require_nothing (GsdUpdatesFirmware *firmware)
937++{
938++ const gchar *message;
939++ gboolean ret;
940++ GError *error = NULL;
941++ NotifyNotification *notification;
942++
943++ /* TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware */
944++ message = _("Your hardware has been set up and is now ready to use.");
945++
946++ /* TRANSLATORS: title of libnotify bubble */
947++ notification = notify_notification_new (_("Additional software was installed"), message, NULL);
948++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
949++ notify_notification_set_app_name (notification, _("Software Updates"));
950++ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
951++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
952++ g_signal_connect (notification, "closed",
953++ G_CALLBACK (on_notification_closed), NULL);
954++
955++ /* show the bubble */
956++ ret = notify_notification_show (notification, &error);
957++ if (!ret) {
958++ g_warning ("error: %s", error->message);
959++ g_error_free (error);
960++ }
961++}
962++
963++static void
964++install_packages_cb (GObject *object,
965++ GAsyncResult *res,
966++ GsdUpdatesFirmware *firmware)
967++{
968++ PkClient *client = PK_CLIENT (object);
969++ GError *error = NULL;
970++ PkResults *results = NULL;
971++ GPtrArray *array = NULL;
972++ gboolean restart = FALSE;
973++ const GsdUpdatesFirmwareRequest *req;
974++ gboolean ret;
975++ guint i;
976++ PkError *error_code = NULL;
977++
978++ /* get the results */
979++ results = pk_client_generic_finish (client, res, &error);
980++ if (results == NULL) {
981++ g_warning ("failed to install file: %s", error->message);
982++ g_error_free (error);
983++ goto out;
984++ }
985++
986++ /* check error code */
987++ error_code = pk_results_get_error_code (results);
988++ if (error_code != NULL) {
989++ g_warning ("failed to install file: %s, %s",
990++ pk_error_enum_to_string (pk_error_get_code (error_code)),
991++ pk_error_get_details (error_code));
992++ goto out;
993++ }
994++
995++ /* go through all the requests, and find the worst type */
996++ array = firmware->priv->array_requested;
997++ for (i=0; i<array->len; i++) {
998++ req = g_ptr_array_index (array, i);
999++ ret = subsystem_can_replug (req->subsystem);
1000++ if (!ret) {
1001++ restart = TRUE;
1002++ break;
1003++ }
1004++ }
1005++
1006++ /* can we just rebind the device */
1007++ ret = g_file_test (GSD_UPDATES_FIRMWARE_DEVICE_REBIND_PROGRAM, G_FILE_TEST_EXISTS);
1008++ if (ret) {
1009++ ret = device_rebind (firmware);
1010++ if (ret) {
1011++ require_nothing (firmware);
1012++ goto out;
1013++ }
1014++ } else {
1015++ /* give the user the correct message */
1016++ if (restart)
1017++ require_restart (firmware);
1018++ else
1019++ require_replug (firmware);
1020++ }
1021++
1022++ /* clear array */
1023++ g_ptr_array_set_size (firmware->priv->array_requested, 0);
1024++out:
1025++ if (error_code != NULL)
1026++ g_object_unref (error_code);
1027++ if (array != NULL)
1028++ g_ptr_array_unref (array);
1029++ if (results != NULL)
1030++ g_object_unref (results);
1031++}
1032++
1033++static gchar **
1034++package_array_to_strv (GPtrArray *array)
1035++{
1036++ PkPackage *item;
1037++ gchar **results;
1038++ guint i;
1039++
1040++ results = g_new0 (gchar *, array->len+1);
1041++ for (i=0; i<array->len; i++) {
1042++ item = g_ptr_array_index (array, i);
1043++ results[i] = g_strdup (pk_package_get_id (item));
1044++ }
1045++ return results;
1046++}
1047++
1048++static void
1049++install_package_ids (GsdUpdatesFirmware *firmware)
1050++{
1051++ gchar **package_ids;
1052++
1053++ /* install all of the firmware files */
1054++ package_ids = package_array_to_strv (firmware->priv->packages_found);
1055++ pk_client_install_packages_async (PK_CLIENT(firmware->priv->task),
1056++ TRUE, package_ids,
1057++ NULL,
1058++ NULL, NULL,
1059++ (GAsyncReadyCallback) install_packages_cb,
1060++ firmware);
1061++ g_strfreev (package_ids);
1062++}
1063++
1064++static void
1065++ignore_devices (GsdUpdatesFirmware *firmware)
1066++{
1067++ gchar *existing = NULL;
1068++ GsdUpdatesFirmwareRequest *req;
1069++ GPtrArray *array;
1070++ GString *string;
1071++ guint i;
1072++
1073++ /* get from settings */
1074++ existing = g_settings_get_string (firmware->priv->settings,
1075++ GSD_SETTINGS_IGNORED_DEVICES);
1076++
1077++ /* get existing string */
1078++ string = g_string_new (existing);
1079++ if (string->len > 0)
1080++ g_string_append (string, ",");
1081++
1082++ /* add all listed devices */
1083++ array = firmware->priv->array_requested;
1084++ for (i=0; i<array->len; i++) {
1085++ req = g_ptr_array_index (array, i);
1086++ g_string_append_printf (string, "%s,", req->id);
1087++ }
1088++
1089++ /* remove final ',' */
1090++ if (string->len > 2)
1091++ g_string_set_size (string, string->len - 1);
1092++
1093++ /* set new string */
1094++ g_settings_set_string (firmware->priv->settings,
1095++ GSD_SETTINGS_IGNORED_DEVICES,
1096++ string->str);
1097++
1098++ g_free (existing);
1099++ g_string_free (string, TRUE);
1100++}
1101++
1102++static PkPackage *
1103++check_available (GsdUpdatesFirmware *firmware, const gchar *filename)
1104++{
1105++ guint length = 0;
1106++ GPtrArray *array = NULL;
1107++ GError *error = NULL;
1108++ PkPackage *item = NULL;
1109++ PkBitfield filter;
1110++ PkResults *results;
1111++ gchar **values = NULL;
1112++ PkError *error_code = NULL;
1113++
1114++ /* search for newest not installed package */
1115++ filter = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED,
1116++ PK_FILTER_ENUM_NEWEST, -1);
1117++ values = g_strsplit (filename, "&", -1);
1118++ results = pk_client_search_files (PK_CLIENT(firmware->priv->task),
1119++ filter,
1120++ values,
1121++ NULL,
1122++ NULL, NULL,
1123++ &error);
1124++ if (results == NULL) {
1125++ g_warning ("failed to search file %s: %s",
1126++ filename, error->message);
1127++ g_error_free (error);
1128++ goto out;
1129++ }
1130++
1131++ /* check error code */
1132++ error_code = pk_results_get_error_code (results);
1133++ if (error_code != NULL) {
1134++ g_warning ("failed to search file: %s, %s",
1135++ pk_error_enum_to_string (pk_error_get_code (error_code)),
1136++ pk_error_get_details (error_code));
1137++ goto out;
1138++ }
1139++
1140++ /* make sure we have one package */
1141++ array = pk_results_get_package_array (results);
1142++ if (array->len == 0)
1143++ g_debug ("no package providing %s found", filename);
1144++ else if (array->len != 1)
1145++ g_warning ("not one package providing %s found (%i)", filename, length);
1146++ else
1147++ item = g_object_ref (g_ptr_array_index (array, 0));
1148++out:
1149++ g_strfreev (values);
1150++ if (error_code != NULL)
1151++ g_object_unref (error_code);
1152++ if (array != NULL)
1153++ g_ptr_array_unref (array);
1154++ if (results != NULL)
1155++ g_object_unref (results);
1156++ return item;
1157++}
1158++
1159++static void
1160++remove_duplicate (GPtrArray *array)
1161++{
1162++ guint i, j;
1163++ const gchar *val;
1164++ const gchar *val_tmp;
1165++
1166++ /* remove each duplicate entry */
1167++ for (i=0; i<array->len; i++) {
1168++ val = g_ptr_array_index (array, i);
1169++ for (j=i+1; j<array->len; j++) {
1170++ val_tmp = g_ptr_array_index (array, j);
1171++ if (g_strcmp0 (val_tmp, val) == 0)
1172++ g_ptr_array_remove_index_fast (array, j);
1173++ }
1174++ }
1175++}
1176++
1177++static gboolean
1178++delay_timeout_cb (gpointer data)
1179++{
1180++ guint i;
1181++ gboolean ret;
1182++ GString *string;
1183++ GsdUpdatesFirmware *firmware = GSD_UPDATES_FIRMWARE (data);
1184++ NotifyNotification *notification;
1185++ GPtrArray *array;
1186++ GError *error = NULL;
1187++ PkPackage *item = NULL;
1188++ const GsdUpdatesFirmwareRequest *req;
1189++ gboolean has_data = FALSE;
1190++
1191++ /* message string */
1192++ string = g_string_new ("");
1193++
1194++ /* try to find each firmware file in an available package */
1195++ array = firmware->priv->array_requested;
1196++ for (i=0; i<array->len; i++) {
1197++ req = g_ptr_array_index (array, i);
1198++ /* save to new array if we found one package for this file */
1199++ item = check_available (firmware, req->filename);
1200++ if (item != NULL) {
1201++ g_ptr_array_add (firmware->priv->packages_found, item);
1202++ g_object_unref (item);
1203++ }
1204++ }
1205++
1206++ /* nothing to do */
1207++ if (firmware->priv->packages_found->len == 0) {
1208++ g_debug ("no packages providing any of the missing firmware");
1209++ goto out;
1210++ }
1211++
1212++ /* check we don't want the same package more than once */
1213++ remove_duplicate (firmware->priv->packages_found);
1214++
1215++ /* have we got any models to array */
1216++ for (i=0; i<array->len; i++) {
1217++ req = g_ptr_array_index (array, i);
1218++ if (req->model != NULL) {
1219++ has_data = TRUE;
1220++ break;
1221++ }
1222++ }
1223++
1224++ /* TRANSLATORS: we need another package to keep udev quiet */
1225++ g_string_append (string, _("Additional firmware is required to make hardware in this computer function correctly."));
1226++
1227++ /* sdd what information we have */
1228++ if (has_data) {
1229++ g_string_append (string, "\n");
1230++ for (i=0; i<array->len; i++) {
1231++ req = g_ptr_array_index (array, i);
1232++ if (req->model != NULL)
1233++ g_string_append_printf (string, "\n• %s", req->model);
1234++ }
1235++ g_string_append (string, "\n");
1236++ }
1237++
1238++ /* TRANSLATORS: title of libnotify bubble */
1239++ notification = notify_notification_new (_("Additional firmware required"), string->str, NULL);
1240++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
1241++ notify_notification_set_app_name (notification, _("Software Updates"));
1242++ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
1243++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
1244++ notify_notification_add_action (notification, "install-firmware",
1245++ /* TRANSLATORS: button label */
1246++ _("Install firmware"), libnotify_cb, firmware, NULL);
1247++ notify_notification_add_action (notification, "ignore-devices",
1248++ /* TRANSLATORS: we should ignore this device and not ask anymore */
1249++ _("Ignore devices"), libnotify_cb, firmware, NULL);
1250++ g_signal_connect (notification, "closed",
1251++ G_CALLBACK (on_notification_closed), NULL);
1252++
1253++ ret = notify_notification_show (notification, &error);
1254++ if (!ret) {
1255++ g_warning ("error: %s", error->message);
1256++ g_error_free (error);
1257++ }
1258++
1259++out:
1260++ g_string_free (string, TRUE);
1261++ /* never repeat */
1262++ return FALSE;
1263++}
1264++
1265++static void
1266++remove_banned (GsdUpdatesFirmware *firmware, GPtrArray *array)
1267++{
1268++ gboolean ret;
1269++ gchar **banned = NULL;
1270++ gchar *banned_str;
1271++ GsdUpdatesFirmwareRequest *req;
1272++ guint i, j;
1273++
1274++ /* get from settings */
1275++ banned_str = g_settings_get_string (firmware->priv->settings,
1276++ GSD_SETTINGS_BANNED_FIRMWARE);
1277++ if (banned_str == NULL) {
1278++ g_warning ("could not read banned list");
1279++ goto out;
1280++ }
1281++
1282++ /* nothing in list, common case */
1283++ if (banned_str[0] == '\0') {
1284++ g_debug ("nothing in banned list");
1285++ goto out;
1286++ }
1287++
1288++ /* split using "," */
1289++ banned = g_strsplit (banned_str, ",", 0);
1290++
1291++ /* remove any banned pattern matches */
1292++ i = 0;
1293++ while (i < array->len) {
1294++ ret = FALSE;
1295++ req = g_ptr_array_index (array, i);
1296++ for (j=0; banned[j] != NULL; j++) {
1297++ ret = g_pattern_match_simple (banned[j], req->filename);
1298++ if (ret) {
1299++ g_debug ("match %s for %s, removing",
1300++ banned[j], req->filename);
1301++ g_ptr_array_remove_index_fast (array, i);
1302++ break;
1303++ }
1304++ }
1305++ if (!ret)
1306++ i++;
1307++ }
1308++out:
1309++ g_free (banned_str);
1310++ g_strfreev (banned);
1311++}
1312++
1313++static void
1314++remove_ignored (GsdUpdatesFirmware *firmware, GPtrArray *array)
1315++{
1316++ gboolean ret;
1317++ gchar **ignored = NULL;
1318++ gchar *ignored_str;
1319++ GsdUpdatesFirmwareRequest *req;
1320++ guint i, j;
1321++
1322++ /* get from settings */
1323++ ignored_str = g_settings_get_string (firmware->priv->settings,
1324++ GSD_SETTINGS_IGNORED_DEVICES);
1325++ if (ignored_str == NULL) {
1326++ g_warning ("could not read ignored list");
1327++ goto out;
1328++ }
1329++
1330++ /* nothing in list, common case */
1331++ if (ignored_str[0] == '\0') {
1332++ g_debug ("nothing in ignored list");
1333++ goto out;
1334++ }
1335++
1336++ /* split using "," */
1337++ ignored = g_strsplit (ignored_str, ",", 0);
1338++
1339++ /* remove any ignored pattern matches */
1340++ i = 0;
1341++ while (i < array->len) {
1342++ ret = FALSE;
1343++ req = g_ptr_array_index (array, i);
1344++ if (req->id == NULL)
1345++ continue;
1346++ for (j=0; ignored[j] != NULL; j++) {
1347++ ret = g_pattern_match_simple (ignored[j], req->id);
1348++ if (ret) {
1349++ g_debug ("match %s for %s, removing", ignored[j], req->id);
1350++ g_ptr_array_remove_index_fast (array, i);
1351++ break;
1352++ }
1353++ }
1354++ if (!ret)
1355++ i++;
1356++ }
1357++out:
1358++ g_free (ignored_str);
1359++ g_strfreev (ignored);
1360++}
1361++
1362++static gchar *
1363++udev_text_decode (const gchar *data)
1364++{
1365++ guint i;
1366++ guint j;
1367++ gchar *decode;
1368++
1369++ decode = g_strdup (data);
1370++ for (i = 0, j = 0; data[i] != '\0'; j++) {
1371++ if (memcmp (&data[i], "\\x2f", 4) == 0) {
1372++ decode[j] = '/';
1373++ i += 4;
1374++ } else if (memcmp (&data[i], "\\x5c", 4) == 0) {
1375++ decode[j] = '\\';
1376++ i += 4;
1377++ } else {
1378++ decode[j] = data[i];
1379++ i++;
1380++ }
1381++ }
1382++ decode[j] = '\0';
1383++ return decode;
1384++}
1385++
1386++static gchar *
1387++get_device (GsdUpdatesFirmware *firmware, const gchar *filename)
1388++{
1389++ GFile *file;
1390++ GFileInfo *info;
1391++ const gchar *symlink_path;
1392++ gchar *syspath = NULL;
1393++ GError *error = NULL;
1394++ gchar *target = NULL;
1395++ gchar *tmp;
1396++
1397++ /* get the file data */
1398++ file = g_file_new_for_path (filename);
1399++ info = g_file_query_info (file,
1400++ G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
1401++ G_FILE_QUERY_INFO_NONE,
1402++ NULL,
1403++ &error);
1404++ if (info == NULL) {
1405++ g_warning ("Failed to get symlink: %s",
1406++ error->message);
1407++ g_error_free (error);
1408++ goto out;
1409++ }
1410++
1411++ /* /devices/pci0000:00/0000:00:1d.0/usb5/5-2/firmware/5-2 */
1412++ symlink_path = g_file_info_get_symlink_target (info);
1413++ if (symlink_path == NULL) {
1414++ g_warning ("failed to get symlink target");
1415++ goto out;
1416++ }
1417++
1418++ /* prepend sys to make '/sys/devices/pci0000:00/0000:00:1d.0/usb5/5-2/firmware/5-2' */
1419++ syspath = g_strconcat ("/sys", symlink_path, NULL);
1420++
1421++ /* start with the longest, and try to find a sub-path that exists */
1422++ tmp = &syspath[strlen (syspath)];
1423++ while (tmp != NULL) {
1424++ *tmp = '\0';
1425++ g_debug ("testing %s", target);
1426++ if (g_file_test (syspath, G_FILE_TEST_EXISTS)) {
1427++ target = g_strdup (syspath);
1428++ goto out;
1429++ }
1430++ tmp = g_strrstr (syspath, "/");
1431++ }
1432++out:
1433++ if (info != NULL)
1434++ g_object_unref (info);
1435++ g_object_unref (file);
1436++ g_free (syspath);
1437++ return target;
1438++}
1439++
1440++static void
1441++add_filename (GsdUpdatesFirmware *firmware, const gchar *filename_no_path)
1442++{
1443++ gboolean ret;
1444++ gchar *filename_path = NULL;
1445++ gchar *missing_path = NULL;
1446++ gchar *sysfs_path = NULL;
1447++ GsdUpdatesFirmwareRequest *req;
1448++ GPtrArray *array;
1449++ guint i;
1450++
1451++ /* this is the file we want to load */
1452++ filename_path = g_build_filename (GSD_UPDATES_FIRMWARE_LOADING_DIR,
1453++ filename_no_path, NULL);
1454++
1455++ /* file already exists */
1456++ ret = g_file_test (filename_path, G_FILE_TEST_EXISTS);
1457++ if (ret)
1458++ goto out;
1459++
1460++ /* this is the file that udev created for us */
1461++ missing_path = g_build_filename (GSD_UPDATES_FIRMWARE_MISSING_DIR,
1462++ filename_no_path, NULL);
1463++ g_debug ("filename=%s -> %s", missing_path, filename_path);
1464++
1465++ /* get symlink target */
1466++ sysfs_path = get_device (firmware, missing_path);
1467++ if (sysfs_path == NULL)
1468++ goto out;
1469++
1470++ /* find any previous requests with this path or firmware */
1471++ array = firmware->priv->array_requested;
1472++ for (i=0; i<array->len; i++) {
1473++ req = g_ptr_array_index (array, i);
1474++ if (g_strcmp0 (sysfs_path, req->sysfs_path) == 0) {
1475++ g_debug ("ignoring previous sysfs request for %s",
1476++ sysfs_path);
1477++ goto out;
1478++ }
1479++ if (g_strcmp0 (filename_path, req->filename) == 0) {
1480++ g_debug ("ignoring previous filename request for %s",
1481++ filename_path);
1482++ goto out;
1483++ }
1484++ }
1485++
1486++ /* create new request object */
1487++ req = request_new (filename_path, sysfs_path);
1488++ g_ptr_array_add (firmware->priv->array_requested, req);
1489++out:
1490++ g_free (missing_path);
1491++ g_free (filename_path);
1492++ g_free (sysfs_path);
1493++}
1494++
1495++static void
1496++scan_directory (GsdUpdatesFirmware *firmware)
1497++{
1498++ gboolean ret;
1499++ GError *error = NULL;
1500++ GDir *dir;
1501++ const gchar *filename;
1502++ gchar *filename_decoded;
1503++ guint i;
1504++ GPtrArray *array;
1505++ const GsdUpdatesFirmwareRequest *req;
1506++ guint scan_id = 0;
1507++
1508++ /* should we check and show the user */
1509++ ret = g_settings_get_boolean (firmware->priv->settings,
1510++ GSD_SETTINGS_ENABLE_CHECK_FIRMWARE);
1511++ if (!ret) {
1512++ g_debug ("not showing thanks to GSettings");
1513++ return;
1514++ }
1515++
1516++ /* open the directory of requests */
1517++ dir = g_dir_open (GSD_UPDATES_FIRMWARE_MISSING_DIR, 0, &error);
1518++ if (dir == NULL) {
1519++ if (error->code != G_FILE_ERROR_NOENT) {
1520++ g_warning ("failed to open directory: %s",
1521++ error->message);
1522++ }
1523++ g_error_free (error);
1524++ return;
1525++ }
1526++
1527++ /* find all the firmware requests */
1528++ filename = g_dir_read_name (dir);
1529++ while (filename != NULL) {
1530++
1531++ filename_decoded = udev_text_decode (filename);
1532++ add_filename (firmware, filename_decoded);
1533++ g_free (filename_decoded);
1534++
1535++ /* next file */
1536++ filename = g_dir_read_name (dir);
1537++ }
1538++ g_dir_close (dir);
1539++
1540++ /* debugging */
1541++ array = firmware->priv->array_requested;
1542++ for (i=0; i<array->len; i++) {
1543++ req = g_ptr_array_index (array, i);
1544++ g_debug ("requested: %s", req->filename);
1545++ }
1546++
1547++ /* remove banned files */
1548++ remove_banned (firmware, array);
1549++
1550++ /* remove ignored devices */
1551++ remove_ignored (firmware, array);
1552++
1553++ /* debugging */
1554++ array = firmware->priv->array_requested;
1555++ for (i=0; i<array->len; i++) {
1556++ req = g_ptr_array_index (array, i);
1557++ g_debug ("searching for: %s", req->filename);
1558++ }
1559++
1560++ /* don't spam the user at startup, so wait a little delay */
1561++ if (array->len > 0) {
1562++ scan_id = g_timeout_add_seconds (GSD_UPDATES_FIRMWARE_PROCESS_DELAY,
1563++ delay_timeout_cb,
1564++ firmware);
1565++ g_source_set_name_by_id (scan_id, "[GsdUpdatesFirmware] process");
1566++ }
1567++}
1568++
1569++static gboolean
1570++scan_directory_cb (GsdUpdatesFirmware *firmware)
1571++{
1572++ scan_directory (firmware);
1573++ firmware->priv->timeout_id = 0;
1574++ return FALSE;
1575++}
1576++
1577++static void
1578++monitor_changed_cb (GFileMonitor *monitor,
1579++ GFile *file,
1580++ GFile *other_file,
1581++ GFileMonitorEvent event_type,
1582++ GsdUpdatesFirmware *firmware)
1583++{
1584++ if (firmware->priv->timeout_id > 0) {
1585++ g_debug ("clearing timeout as device changed");
1586++ g_source_remove (firmware->priv->timeout_id);
1587++ }
1588++
1589++ /* wait for the device to settle */
1590++ firmware->priv->timeout_id =
1591++ g_timeout_add_seconds (GSD_UPDATES_FIRMWARE_INSERT_DELAY,
1592++ (GSourceFunc) scan_directory_cb,
1593++ firmware);
1594++ g_source_set_name_by_id (firmware->priv->timeout_id,
1595++ "[GsdUpdatesFirmware] changed");
1596++}
1597++
1598++static void
1599++gsd_updates_firmware_class_init (GsdUpdatesFirmwareClass *klass)
1600++{
1601++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
1602++ object_class->finalize = gsd_updates_firmware_finalize;
1603++ g_type_class_add_private (klass, sizeof (GsdUpdatesFirmwarePrivate));
1604++}
1605++
1606++static void
1607++gsd_updates_firmware_init (GsdUpdatesFirmware *firmware)
1608++{
1609++ GFile *file;
1610++ GError *error = NULL;
1611++
1612++ firmware->priv = GSD_UPDATES_FIRMWARE_GET_PRIVATE (firmware);
1613++ firmware->priv->timeout_id = 0;
1614++ firmware->priv->packages_found = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
1615++ firmware->priv->array_requested = g_ptr_array_new_with_free_func ((GDestroyNotify) request_free);
1616++ firmware->priv->settings = g_settings_new (GSD_SETTINGS_SCHEMA);
1617++ firmware->priv->task = pk_task_new ();
1618++ g_object_set (firmware->priv->task,
1619++ "background", TRUE,
1620++ NULL);
1621++
1622++ /* setup watch for new hardware */
1623++ file = g_file_new_for_path (GSD_UPDATES_FIRMWARE_MISSING_DIR);
1624++ firmware->priv->monitor = g_file_monitor (file,
1625++ G_FILE_MONITOR_NONE,
1626++ NULL,
1627++ &error);
1628++ if (firmware->priv->monitor == NULL) {
1629++ g_warning ("failed to setup monitor: %s", error->message);
1630++ g_error_free (error);
1631++ goto out;
1632++ }
1633++
1634++ /* limit to one per second */
1635++ g_file_monitor_set_rate_limit (firmware->priv->monitor, 1000);
1636++
1637++ /* get notified of changes */
1638++ g_signal_connect (firmware->priv->monitor, "changed",
1639++ G_CALLBACK (monitor_changed_cb), firmware);
1640++out:
1641++ g_object_unref (file);
1642++ firmware->priv->timeout_id =
1643++ g_timeout_add_seconds (GSD_UPDATES_FIRMWARE_LOGIN_DELAY,
1644++ (GSourceFunc) scan_directory_cb,
1645++ firmware);
1646++ g_source_set_name_by_id (firmware->priv->timeout_id,
1647++ "[GsdUpdatesFirmware] login coldplug");
1648++}
1649++
1650++static void
1651++gsd_updates_firmware_finalize (GObject *object)
1652++{
1653++ GsdUpdatesFirmware *firmware;
1654++
1655++ g_return_if_fail (GSD_UPDATES_IS_FIRMWARE (object));
1656++
1657++ firmware = GSD_UPDATES_FIRMWARE (object);
1658++
1659++ g_return_if_fail (firmware->priv != NULL);
1660++ g_ptr_array_unref (firmware->priv->array_requested);
1661++ g_ptr_array_unref (firmware->priv->packages_found);
1662++ g_object_unref (PK_CLIENT(firmware->priv->task));
1663++ g_object_unref (firmware->priv->settings);
1664++ if (firmware->priv->monitor != NULL)
1665++ g_object_unref (firmware->priv->monitor);
1666++ if (firmware->priv->timeout_id > 0)
1667++ g_source_remove (firmware->priv->timeout_id);
1668++
1669++ G_OBJECT_CLASS (gsd_updates_firmware_parent_class)->finalize (object);
1670++}
1671++
1672++GsdUpdatesFirmware *
1673++gsd_updates_firmware_new (void)
1674++{
1675++ GsdUpdatesFirmware *firmware;
1676++ firmware = g_object_new (GSD_UPDATES_TYPE_FIRMWARE, NULL);
1677++ return GSD_UPDATES_FIRMWARE (firmware);
1678++}
1679+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-firmware.h
1680+===================================================================
1681+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1682++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-firmware.h 2014-12-02 00:06:35.437485592 +0100
1683+@@ -0,0 +1,52 @@
1684++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1685++ *
1686++ * Copyright (C) 2007-2011 Richard Hughes <richard@hughsie.com>
1687++ *
1688++ * Licensed under the GNU General Public License Version 2
1689++ *
1690++ * This program is free software; you can redistribute it and/or modify
1691++ * it under the terms of the GNU General Public License as published by
1692++ * the Free Software Foundation; either version 2 of the License, or
1693++ * (at your option) any later version.
1694++ *
1695++ * This program is distributed in the hope that it will be useful,
1696++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1697++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1698++ * GNU General Public License for more details.
1699++ *
1700++ * You should have received a copy of the GNU General Public License
1701++ * along with this program; if not, write to the Free Software
1702++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1703++ */
1704++
1705++#ifndef __GSD_UPDATES_FIRMWARE_H
1706++#define __GSD_UPDATES_FIRMWARE_H
1707++
1708++#include <glib-object.h>
1709++
1710++G_BEGIN_DECLS
1711++
1712++#define GSD_UPDATES_TYPE_FIRMWARE (gsd_updates_firmware_get_type ())
1713++#define GSD_UPDATES_FIRMWARE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_UPDATES_TYPE_FIRMWARE, GsdUpdatesFirmware))
1714++#define GSD_UPDATES_FIRMWARE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_UPDATES_TYPE_FIRMWARE, GsdUpdatesFirmwareClass))
1715++#define GSD_UPDATES_IS_FIRMWARE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_UPDATES_TYPE_FIRMWARE))
1716++
1717++typedef struct GsdUpdatesFirmwarePrivate GsdUpdatesFirmwarePrivate;
1718++
1719++typedef struct
1720++{
1721++ GObject parent;
1722++ GsdUpdatesFirmwarePrivate *priv;
1723++} GsdUpdatesFirmware;
1724++
1725++typedef struct
1726++{
1727++ GObjectClass parent_class;
1728++} GsdUpdatesFirmwareClass;
1729++
1730++GType gsd_updates_firmware_get_type (void);
1731++GsdUpdatesFirmware *gsd_updates_firmware_new (void);
1732++
1733++G_END_DECLS
1734++
1735++#endif /* __GSD_UPDATES_FIRMWARE_H */
1736+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-manager.c
1737+===================================================================
1738+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1739++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-manager.c 2014-12-02 00:06:35.441485533 +0100
1740+@@ -0,0 +1,1519 @@
1741++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
1742++ *
1743++ * Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
1744++ *
1745++ * This program is free software; you can redistribute it and/or modify
1746++ * it under the terms of the GNU General Public License as published by
1747++ * the Free Software Foundation; either version 2 of the License, or
1748++ * (at your option) any later version.
1749++ *
1750++ * This program is distributed in the hope that it will be useful,
1751++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1752++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1753++ * GNU General Public License for more details.
1754++ *
1755++ * You should have received a copy of the GNU General Public License
1756++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
1757++ *
1758++ */
1759++
1760++#include "config.h"
1761++
1762++#include <locale.h>
1763++
1764++#include <glib.h>
1765++#include <glib/gi18n.h>
1766++#include <gtk/gtk.h>
1767++#include <packagekit-glib2/packagekit.h>
1768++#include <libnotify/notify.h>
1769++#include <gdesktop-enums.h>
1770++
1771++#include "gsd-enums.h"
1772++#include "gsd-updates-manager.h"
1773++#include "gsd-updates-firmware.h"
1774++#include "gsd-updates-refresh.h"
1775++#include "gsd-updates-common.h"
1776++#include "gnome-settings-profile.h"
1777++#include "gnome-settings-bus.h"
1778++
1779++#define GSD_UPDATES_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_UPDATES_MANAGER, GsdUpdatesManagerPrivate))
1780++
1781++#define MAX_FAILED_GET_UPDATES 10 /* the maximum number of tries */
1782++#define GSD_UPDATES_ICON_NORMAL "software-update-available-symbolic"
1783++#define GSD_UPDATES_ICON_URGENT "software-update-urgent-symbolic"
1784++#define GSD_UPDATES_CHECK_OFFLINE_TIMEOUT 30 /* time in seconds */
1785++
1786++struct GsdUpdatesManagerPrivate
1787++{
1788++ GCancellable *cancellable;
1789++ GsdUpdatesRefresh *refresh;
1790++ GsdUpdatesFirmware *firmware;
1791++ GSettings *settings_proxy;
1792++ GSettings *settings_ftp;
1793++ GSettings *settings_gsd;
1794++ GSettings *settings_http;
1795++ guint number_updates_critical_last_shown;
1796++ guint offline_update_id;
1797++ PkError *offline_update_error;
1798++ NotifyNotification *notification_updates;
1799++ NotifyNotification *notification_offline_success;
1800++ PkControl *control;
1801++ PkTask *task;
1802++ guint inhibit_cookie;
1803++ GsdSessionManager *proxy_session;
1804++ guint update_viewer_watcher_id;
1805++ GVolumeMonitor *volume_monitor;
1806++ guint failed_get_updates_count;
1807++ GPtrArray *update_packages;
1808++};
1809++
1810++static void gsd_updates_manager_class_init (GsdUpdatesManagerClass *klass);
1811++static void gsd_updates_manager_init (GsdUpdatesManager *updates_manager);
1812++static void restart_and_install_updates (void);
1813++
1814++G_DEFINE_TYPE (GsdUpdatesManager, gsd_updates_manager, G_TYPE_OBJECT)
1815++
1816++static gpointer manager_object = NULL;
1817++
1818++static void
1819++child_exit_cb (GPid pid, gint status, gpointer user_data)
1820++{
1821++ g_spawn_close_pid (pid);
1822++}
1823++
1824++static void
1825++clear_offline_updates_message (void)
1826++{
1827++ gboolean ret;
1828++ GError *error = NULL;
1829++ gchar *argv[3];
1830++ GPid pid;
1831++
1832++ argv[0] = "pkexec";
1833++ argv[1] = LIBEXECDIR "/pk-clear-offline-update";
1834++ argv[2] = NULL;
1835++ ret = g_spawn_async (NULL,
1836++ argv,
1837++ NULL,
1838++ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
1839++ NULL,
1840++ NULL,
1841++ &pid,
1842++ &error);
1843++ if (!ret) {
1844++ g_warning ("Failure clearing offline update message: %s",
1845++ error->message);
1846++ g_error_free (error);
1847++ return;
1848++ }
1849++ g_child_watch_add (pid, child_exit_cb, NULL);
1850++}
1851++
1852++static void
1853++show_offline_updates_error (GsdUpdatesManager *manager)
1854++{
1855++ const gchar *title;
1856++ gboolean show_geeky = FALSE;
1857++ GString *msg;
1858++ GtkWidget *dialog;
1859++
1860++ /* TRANSLATORS: this is when the offline update failed */
1861++ title = _("Failed To Update");
1862++ msg = g_string_new ("");
1863++ switch (pk_error_get_code (manager->priv->offline_update_error)) {
1864++ case PK_ERROR_ENUM_UNFINISHED_TRANSACTION:
1865++ /* TRANSLATORS: the transaction could not be completed
1866++ * as a previous transaction was unfinished */
1867++ g_string_append (msg, _("A previous update was unfinished."));
1868++ show_geeky = TRUE;
1869++ break;
1870++ case PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED:
1871++ case PK_ERROR_ENUM_NO_CACHE:
1872++ case PK_ERROR_ENUM_NO_NETWORK:
1873++ case PK_ERROR_ENUM_NO_MORE_MIRRORS_TO_TRY:
1874++ case PK_ERROR_ENUM_CANNOT_FETCH_SOURCES:
1875++ /* TRANSLATORS: the package manager needed to download
1876++ * something with no network available */
1877++ g_string_append (msg, _("Network access was required but not available."));
1878++ break;
1879++ case PK_ERROR_ENUM_BAD_GPG_SIGNATURE:
1880++ case PK_ERROR_ENUM_CANNOT_UPDATE_REPO_UNSIGNED:
1881++ case PK_ERROR_ENUM_GPG_FAILURE:
1882++ case PK_ERROR_ENUM_MISSING_GPG_SIGNATURE:
1883++ case PK_ERROR_ENUM_PACKAGE_CORRUPT:
1884++ /* TRANSLATORS: if the package is not signed correctly
1885++ * */
1886++ g_string_append (msg, _("An update was not signed in the correct way."));
1887++ show_geeky = TRUE;
1888++ break;
1889++ case PK_ERROR_ENUM_DEP_RESOLUTION_FAILED:
1890++ case PK_ERROR_ENUM_FILE_CONFLICTS:
1891++ case PK_ERROR_ENUM_INCOMPATIBLE_ARCHITECTURE:
1892++ case PK_ERROR_ENUM_PACKAGE_CONFLICTS:
1893++ /* TRANSLATORS: the transaction failed in a way the user
1894++ * probably cannot comprehend. Package management systems
1895++ * really are teh suck.*/
1896++ g_string_append (msg, _("The update could not be completed."));
1897++ show_geeky = TRUE;
1898++ break;
1899++ case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
1900++ /* TRANSLATORS: the user aborted the update manually */
1901++ g_string_append (msg, _("The update was cancelled."));
1902++ break;
1903++ case PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE:
1904++ case PK_ERROR_ENUM_UPDATE_NOT_FOUND:
1905++ /* TRANSLATORS: the user must have updated manually after
1906++ * the updates were prepared */
1907++ g_string_append (msg, _("An offline update was requested but no packages required updating."));
1908++ break;
1909++ case PK_ERROR_ENUM_NO_SPACE_ON_DEVICE:
1910++ /* TRANSLATORS: we ran out of disk space */
1911++ g_string_append (msg, _("No space was left on the drive."));
1912++ break;
1913++ case PK_ERROR_ENUM_PACKAGE_FAILED_TO_BUILD:
1914++ case PK_ERROR_ENUM_PACKAGE_FAILED_TO_INSTALL:
1915++ case PK_ERROR_ENUM_PACKAGE_FAILED_TO_REMOVE:
1916++ /* TRANSLATORS: the update process failed in a general
1917++ * way, usually this message will come from source distros
1918++ * like gentoo */
1919++ g_string_append (msg, _("An update failed to install correctly."));
1920++ show_geeky = TRUE;
1921++ break;
1922++ default:
1923++ /* TRANSLATORS: We didn't handle the error type */
1924++ g_string_append (msg, _("The offline update failed in an unexpected way."));
1925++ show_geeky = TRUE;
1926++ break;
1927++ }
1928++ if (show_geeky) {
1929++ g_string_append_printf (msg, "\n%s\n\n%s",
1930++ /* TRANSLATORS: these are geeky messages from the
1931++ * package manager no mortal is supposed to understand,
1932++ * but google might know what they mean */
1933++ _("Detailed errors from the package manager follow:"),
1934++ pk_error_get_details (manager->priv->offline_update_error));
1935++ }
1936++ dialog = gtk_message_dialog_new (NULL,
1937++ 0,
1938++ GTK_MESSAGE_INFO,
1939++ GTK_BUTTONS_CLOSE,
1940++ "%s", title);
1941++ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
1942++ "%s", msg->str);
1943++ g_signal_connect_swapped (dialog, "response",
1944++ G_CALLBACK (gtk_widget_destroy),
1945++ dialog);
1946++ gtk_widget_show (dialog);
1947++ clear_offline_updates_message ();
1948++ g_string_free (msg, TRUE);
1949++}
1950++
1951++static gboolean
1952++does_gnome_software_exist (void)
1953++{
1954++ return g_file_test (BINDIR "/gnome-software", G_FILE_TEST_EXISTS);
1955++}
1956++
1957++static void
1958++libnotify_action_cb (NotifyNotification *notification,
1959++ gchar *action,
1960++ gpointer user_data)
1961++{
1962++ gboolean ret;
1963++ GError *error = NULL;
1964++ GsdUpdatesManager *manager = GSD_UPDATES_MANAGER (user_data);
1965++
1966++ notify_notification_close (notification, NULL);
1967++ if (g_strcmp0 (action, "ignore") == 0)
1968++ goto out;
1969++ if (g_strcmp0 (action, "distro-upgrade-info") == 0) {
1970++ ret = g_spawn_command_line_async (DATADIR "/PackageKit/pk-upgrade-distro.sh",
1971++ &error);
1972++ if (!ret) {
1973++ g_warning ("Failure launching pk-upgrade-distro.sh: %s",
1974++ error->message);
1975++ g_error_free (error);
1976++ }
1977++ goto out;
1978++ }
1979++ if (g_strcmp0 (action, "show-update-viewer") == 0) {
1980++ ret = g_spawn_command_line_async (BINDIR "/gpk-update-viewer",
1981++ &error);
1982++ if (!ret) {
1983++ g_warning ("Failure launching update viewer: %s",
1984++ error->message);
1985++ g_error_free (error);
1986++ }
1987++ goto out;
1988++ }
1989++ if (g_strcmp0 (action, "clear-offline-updates") == 0) {
1990++ clear_offline_updates_message ();
1991++ goto out;
1992++ }
1993++ if (g_strcmp0 (action, "error-offline-updates") == 0) {
1994++ show_offline_updates_error (manager);
1995++ goto out;
1996++ }
1997++ if (g_strcmp0 (action, "install") == 0) {
1998++ restart_and_install_updates ();
1999++ goto out;
2000++ }
2001++ if (g_strcmp0 (action, "cancel") == 0) {
2002++ /* try to cancel */
2003++ g_cancellable_cancel (manager->priv->cancellable);
2004++ goto out;
2005++ }
2006++ g_warning ("unknown action id: %s", action);
2007++out:
2008++ return;
2009++}
2010++
2011++static void
2012++on_notification_closed (NotifyNotification *notification, gpointer data)
2013++{
2014++ g_object_unref (notification);
2015++}
2016++
2017++static void
2018++get_distro_upgrades_finished_cb (GObject *object,
2019++ GAsyncResult *res,
2020++ GsdUpdatesManager *manager)
2021++{
2022++ const gchar *title;
2023++ gboolean ret;
2024++ gchar *name = NULL;
2025++ GError *error = NULL;
2026++ GPtrArray *array = NULL;
2027++ GString *string = NULL;
2028++ guint i;
2029++ NotifyNotification *notification;
2030++ PkClient *client = PK_CLIENT(object);
2031++ PkDistroUpgrade *item;
2032++ PkError *error_code = NULL;
2033++ PkResults *results;
2034++ PkUpdateStateEnum state;
2035++
2036++ /* get the results */
2037++ results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
2038++ if (results == NULL) {
2039++ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2040++ g_error_free (error);
2041++ return;
2042++ }
2043++ if (error->domain != PK_CLIENT_ERROR ||
2044++ error->code != PK_CLIENT_ERROR_NOT_SUPPORTED) {
2045++ g_warning ("failed to get upgrades: %s",
2046++ error->message);
2047++ }
2048++ g_error_free (error);
2049++ goto out;
2050++ }
2051++
2052++ /* check error code */
2053++ error_code = pk_results_get_error_code (results);
2054++ if (error_code != NULL) {
2055++ g_warning ("failed to get upgrades: %s, %s",
2056++ pk_error_enum_to_string (pk_error_get_code (error_code)),
2057++ pk_error_get_details (error_code));
2058++ goto out;
2059++ }
2060++
2061++ /* process results */
2062++ array = pk_results_get_distro_upgrade_array (results);
2063++
2064++ /* any updates? */
2065++ if (array->len == 0) {
2066++ g_debug ("no upgrades");
2067++ goto out;
2068++ }
2069++
2070++ /* do we do the notification? */
2071++ ret = g_settings_get_boolean (manager->priv->settings_gsd,
2072++ GSD_SETTINGS_NOTIFY_DISTRO_UPGRADES);
2073++ if (!ret) {
2074++ g_debug ("ignoring due to GSettings");
2075++ goto out;
2076++ }
2077++
2078++ /* find the upgrade string */
2079++ string = g_string_new ("");
2080++ for (i=0; i < array->len; i++) {
2081++ item = (PkDistroUpgrade *) g_ptr_array_index (array, i);
2082++ g_object_get (item,
2083++ "name", &name,
2084++ "state", &state,
2085++ NULL);
2086++ g_string_append_printf (string, "%s (%s)\n",
2087++ name,
2088++ pk_distro_upgrade_enum_to_string (state));
2089++ g_free (name);
2090++ }
2091++ if (string->len != 0)
2092++ g_string_set_size (string, string->len-1);
2093++
2094++ /* TRANSLATORS: a distro update is available, e.g. Fedora 8 to Fedora 9 */
2095++ title = _("Distribution upgrades available");
2096++ notification = notify_notification_new (title,
2097++ string->str,
2098++ GSD_UPDATES_ICON_NORMAL);
2099++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
2100++ notify_notification_set_app_name (notification, _("Software Updates"));
2101++ notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
2102++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
2103++ notify_notification_add_action (notification, "ignore",
2104++ /* TRANSLATORS: don't install updates now */
2105++ _("Not Now"),
2106++ libnotify_action_cb,
2107++ manager, NULL);
2108++ notify_notification_add_action (notification, "distro-upgrade-info",
2109++ /* TRANSLATORS: provides more information about the upgrade */
2110++ _("More information"),
2111++ libnotify_action_cb,
2112++ manager, NULL);
2113++ g_signal_connect (notification, "closed",
2114++ G_CALLBACK (on_notification_closed), NULL);
2115++ ret = notify_notification_show (notification, &error);
2116++ if (!ret) {
2117++ g_warning ("error: %s", error->message);
2118++ g_error_free (error);
2119++ }
2120++out:
2121++ if (error_code != NULL)
2122++ g_object_unref (error_code);
2123++ if (array != NULL)
2124++ g_ptr_array_unref (array);
2125++ if (string != NULL)
2126++ g_string_free (string, TRUE);
2127++ if (results != NULL)
2128++ g_object_unref (results);
2129++}
2130++
2131++static void
2132++due_get_upgrades_cb (GsdUpdatesRefresh *refresh, GsdUpdatesManager *manager)
2133++{
2134++ /* optimize the amount of downloaded data by setting the cache age */
2135++ pk_client_set_cache_age (PK_CLIENT(manager->priv->task),
2136++ g_settings_get_int (manager->priv->settings_gsd,
2137++ GSD_SETTINGS_FREQUENCY_GET_UPGRADES));
2138++
2139++ /* get new distro upgrades list */
2140++ pk_client_get_distro_upgrades_async (PK_CLIENT(manager->priv->task),
2141++ NULL,
2142++ NULL, NULL,
2143++ (GAsyncReadyCallback) get_distro_upgrades_finished_cb,
2144++ manager);
2145++}
2146++
2147++static void
2148++refresh_cache_finished_cb (GObject *object, GAsyncResult *res, GsdUpdatesManager *manager)
2149++{
2150++ PkClient *client = PK_CLIENT(object);
2151++ PkResults *results;
2152++ GError *error = NULL;
2153++ PkError *error_code = NULL;
2154++
2155++ /* get the results */
2156++ results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
2157++ if (results == NULL) {
2158++ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2159++ g_error_free (error);
2160++ return;
2161++ }
2162++ g_warning ("failed to refresh the cache: %s",
2163++ error->message);
2164++ g_error_free (error);
2165++ return;
2166++ }
2167++
2168++ /* check error code */
2169++ error_code = pk_results_get_error_code (results);
2170++ if (error_code != NULL) {
2171++ g_warning ("failed to refresh the cache: %s, %s",
2172++ pk_error_enum_to_string (pk_error_get_code (error_code)),
2173++ pk_error_get_details (error_code));
2174++ }
2175++
2176++ if (error_code != NULL)
2177++ g_object_unref (error_code);
2178++ if (results != NULL)
2179++ g_object_unref (results);
2180++}
2181++
2182++static void
2183++due_refresh_cache_cb (GsdUpdatesRefresh *refresh, GsdUpdatesManager *manager)
2184++{
2185++ /* optimize the amount of downloaded data by setting the cache age */
2186++ pk_client_set_cache_age (PK_CLIENT(manager->priv->task),
2187++ g_settings_get_int (manager->priv->settings_gsd,
2188++ GSD_SETTINGS_FREQUENCY_REFRESH_CACHE));
2189++
2190++ pk_client_refresh_cache_async (PK_CLIENT(manager->priv->task),
2191++ TRUE,
2192++ NULL,
2193++ NULL, NULL,
2194++ (GAsyncReadyCallback) refresh_cache_finished_cb,
2195++ manager);
2196++}
2197++
2198++static void
2199++notify_critical_updates (GsdUpdatesManager *manager, GPtrArray *array)
2200++{
2201++ const gchar *message;
2202++ const gchar *title;
2203++ gboolean ret;
2204++ GError *error = NULL;
2205++ NotifyNotification *notification;
2206++
2207++ /* if the number of critical updates is the same as the last notification,
2208++ * then skip the notifcation as we don't want to bombard the user every hour */
2209++ if (array->len == manager->priv->number_updates_critical_last_shown) {
2210++ g_debug ("ignoring as user ignored last warning");
2211++ return;
2212++ }
2213++
2214++ /* save for comparison later */
2215++ manager->priv->number_updates_critical_last_shown = array->len;
2216++
2217++ /* TRANSLATORS: title in the libnotify popup */
2218++ title = ngettext ("Update", "Updates", array->len);
2219++
2220++ /* TRANSLATORS: message when there are security updates */
2221++ message = ngettext ("An important software update is available",
2222++ "Important software updates are available", array->len);
2223++
2224++ /* close any existing notification */
2225++ if (manager->priv->notification_updates != NULL) {
2226++ notify_notification_close (manager->priv->notification_updates, NULL);
2227++ manager->priv->notification_updates = NULL;
2228++ }
2229++
2230++ /* do the bubble */
2231++ g_debug ("title=%s, message=%s", title, message);
2232++ notification = notify_notification_new (title,
2233++ message,
2234++ GSD_UPDATES_ICON_URGENT);
2235++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
2236++ notify_notification_set_app_name (notification, _("Software Updates"));
2237++ notify_notification_set_timeout (notification, 15000);
2238++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
2239++ notify_notification_add_action (notification, "ignore",
2240++ /* TRANSLATORS: don't install updates now */
2241++ _("Not Now"),
2242++ libnotify_action_cb,
2243++ manager, NULL);
2244++ notify_notification_add_action (notification, "show-update-viewer",
2245++ /* TRANSLATORS: button: open the update viewer to install updates */
2246++ _("Install updates"), libnotify_action_cb, manager, NULL);
2247++ g_signal_connect (notification, "closed",
2248++ G_CALLBACK (on_notification_closed), NULL);
2249++ ret = notify_notification_show (notification, &error);
2250++ if (!ret) {
2251++ g_warning ("error: %s", error->message);
2252++ g_error_free (error);
2253++ }
2254++ /* track so we can prevent doubled notifications */
2255++ manager->priv->notification_updates = notification;
2256++ g_object_add_weak_pointer (G_OBJECT (manager->priv->notification_updates),
2257++ (void **) &manager->priv->notification_updates);
2258++}
2259++
2260++static void
2261++notify_normal_updates_maybe (GsdUpdatesManager *manager, GPtrArray *array)
2262++{
2263++ const gchar *message;
2264++ const gchar *title;
2265++ gboolean ret;
2266++ GError *error = NULL;
2267++ guint64 time_last_notify;
2268++ guint64 time_now;
2269++ guint freq_updates_notify;
2270++ NotifyNotification *notification;
2271++
2272++ /* find out if enough time has passed since the last notification */
2273++ time_now = g_get_real_time () / 1000000;
2274++ freq_updates_notify = g_settings_get_int (manager->priv->settings_gsd,
2275++ GSD_SETTINGS_FREQUENCY_UPDATES_NOTIFICATION);
2276++ g_settings_get (manager->priv->settings_gsd,
2277++ GSD_SETTINGS_LAST_UPDATES_NOTIFICATION,
2278++ "t", &time_last_notify);
2279++ if (time_last_notify > 0 &&
2280++ (guint64) freq_updates_notify > time_now - time_last_notify) {
2281++ g_debug ("not showing non-critical notification as already shown %i hours ago",
2282++ (guint) (time_now - time_last_notify) / (60 * 60));
2283++ return;
2284++ }
2285++
2286++ /* TRANSLATORS: title in the libnotify popup */
2287++ title = ngettext ("Update", "Updates", array->len);
2288++
2289++ /* TRANSLATORS: message when there are non-security updates */
2290++ message = ngettext ("A software update is available.",
2291++ "Software updates are available.", array->len);
2292++
2293++ /* close any existing notification */
2294++ if (manager->priv->notification_updates != NULL) {
2295++ notify_notification_close (manager->priv->notification_updates, NULL);
2296++ manager->priv->notification_updates = NULL;
2297++ }
2298++
2299++ /* do the bubble */
2300++ g_debug ("title=%s, message=%s", title, message);
2301++ notification = notify_notification_new (title,
2302++ message,
2303++ GSD_UPDATES_ICON_NORMAL);
2304++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
2305++ notify_notification_set_app_name (notification, _("Software Updates"));
2306++ notify_notification_set_timeout (notification, 15000);
2307++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
2308++ notify_notification_add_action (notification, "ignore",
2309++ /* TRANSLATORS: don't install updates now */
2310++ _("Not Now"),
2311++ libnotify_action_cb,
2312++ manager, NULL);
2313++ notify_notification_add_action (notification, "show-update-viewer",
2314++ /* TRANSLATORS: button: open the update viewer to install updates */
2315++ _("Install updates"), libnotify_action_cb, manager, NULL);
2316++ g_signal_connect (notification, "closed",
2317++ G_CALLBACK (on_notification_closed), NULL);
2318++ ret = notify_notification_show (notification, &error);
2319++ if (!ret) {
2320++ g_warning ("error: %s", error->message);
2321++ g_error_free (error);
2322++ }
2323++
2324++ /* reset notification time */
2325++ g_settings_set (manager->priv->settings_gsd,
2326++ GSD_SETTINGS_LAST_UPDATES_NOTIFICATION,
2327++ "t", time_now);
2328++
2329++ /* track so we can prevent doubled notifications */
2330++ manager->priv->notification_updates = notification;
2331++ g_object_add_weak_pointer (G_OBJECT (manager->priv->notification_updates),
2332++ (void **) &manager->priv->notification_updates);
2333++}
2334++
2335++static void
2336++notify_failed_get_updates_maybe (GsdUpdatesManager *manager)
2337++{
2338++ const gchar *button;
2339++ const gchar *message;
2340++ const gchar *title;
2341++ gboolean ret;
2342++ GError *error = NULL;
2343++ NotifyNotification *notification;
2344++
2345++ /* give the user a break */
2346++ if (manager->priv->failed_get_updates_count++ < MAX_FAILED_GET_UPDATES) {
2347++ g_debug ("failed GetUpdates, but will retry %i more times before notification",
2348++ MAX_FAILED_GET_UPDATES - manager->priv->failed_get_updates_count);
2349++ goto out;
2350++ }
2351++
2352++ /* TRANSLATORS: the updates mechanism */
2353++ title = _("Updates");
2354++
2355++ /* TRANSLATORS: we failed to get the updates multiple times,
2356++ * and now we need to inform the user that something might be wrong */
2357++ message = _("Unable to access software updates");
2358++
2359++ /* TRANSLATORS: try again, this time launching the update viewer */
2360++ button = _("Try again");
2361++
2362++ notification = notify_notification_new (title,
2363++ message,
2364++ GSD_UPDATES_ICON_NORMAL);
2365++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
2366++ notify_notification_set_app_name (notification, _("Software Updates"));
2367++ notify_notification_set_timeout (notification, 120*1000);
2368++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
2369++ notify_notification_add_action (notification, "show-update-viewer",
2370++ button,
2371++ libnotify_action_cb,
2372++ manager, NULL);
2373++ g_signal_connect (notification, "closed",
2374++ G_CALLBACK (on_notification_closed), NULL);
2375++ ret = notify_notification_show (notification, &error);
2376++ if (!ret) {
2377++ g_warning ("failed to show notification: %s",
2378++ error->message);
2379++ g_error_free (error);
2380++ }
2381++out:
2382++ /* reset, even if the message failed */
2383++ manager->priv->failed_get_updates_count = 0;
2384++}
2385++
2386++static void
2387++check_updates_for_importance (GsdUpdatesManager *manager)
2388++{
2389++ guint i;
2390++ PkPackage *pkg;
2391++ GPtrArray *important_array;
2392++
2393++ /* check each package */
2394++ important_array = g_ptr_array_new ();
2395++ for (i = 0; i < manager->priv->update_packages->len; i++) {
2396++ pkg = g_ptr_array_index (manager->priv->update_packages, i);
2397++ if (pk_package_get_info (pkg) == PK_INFO_ENUM_SECURITY ||
2398++ pk_package_get_info (pkg) == PK_INFO_ENUM_IMPORTANT)
2399++ g_ptr_array_add (important_array, pkg);
2400++ }
2401++ if (important_array->len > 0) {
2402++ notify_critical_updates (manager,
2403++ important_array);
2404++ } else {
2405++ notify_normal_updates_maybe (manager,
2406++ manager->priv->update_packages);
2407++ }
2408++ g_ptr_array_unref (important_array);
2409++}
2410++
2411++static void
2412++package_download_finished_cb (GObject *object,
2413++ GAsyncResult *res,
2414++ GsdUpdatesManager *manager)
2415++{
2416++ PkClient *client = PK_CLIENT(object);
2417++ PkResults *results;
2418++ GError *error = NULL;
2419++ PkError *error_code = NULL;
2420++
2421++ /* get the results */
2422++ results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
2423++ if (results == NULL) {
2424++ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2425++ g_error_free (error);
2426++ return;
2427++ }
2428++ g_warning ("failed to download: %s",
2429++ error->message);
2430++ g_error_free (error);
2431++ notify_failed_get_updates_maybe (manager);
2432++ return;
2433++ }
2434++
2435++ /* check error code */
2436++ error_code = pk_results_get_error_code (results);
2437++ if (error_code != NULL) {
2438++ g_warning ("failed to download: %s, %s",
2439++ pk_error_enum_to_string (pk_error_get_code (error_code)),
2440++ pk_error_get_details (error_code));
2441++ switch (pk_error_get_code (error_code)) {
2442++ case PK_ERROR_ENUM_CANCELLED_PRIORITY:
2443++ case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
2444++ g_debug ("ignoring error");
2445++ break;
2446++ default:
2447++ notify_failed_get_updates_maybe (manager);
2448++ break;
2449++ }
2450++ goto out;
2451++ }
2452++
2453++ /* check to see if should notify */
2454++ check_updates_for_importance (manager);
2455++
2456++out:
2457++ if (error_code != NULL)
2458++ g_object_unref (error_code);
2459++ if (results != NULL)
2460++ g_object_unref (results);
2461++}
2462++
2463++static void
2464++auto_download_updates (GsdUpdatesManager *manager)
2465++{
2466++ gchar **package_ids;
2467++ guint i;
2468++ PkPackage *pkg;
2469++
2470++ /* download each package */
2471++ package_ids = g_new0 (gchar *, manager->priv->update_packages->len + 1);
2472++ for (i = 0; i < manager->priv->update_packages->len; i++) {
2473++ pkg = g_ptr_array_index (manager->priv->update_packages, i);
2474++ package_ids[i] = g_strdup (pk_package_get_id (pkg));
2475++ }
2476++
2477++ /* we've set only-download in PkTask */
2478++ pk_task_update_packages_async (manager->priv->task,
2479++ package_ids,
2480++ manager->priv->cancellable,
2481++ NULL, NULL,
2482++ (GAsyncReadyCallback) package_download_finished_cb,
2483++ manager);
2484++ g_strfreev (package_ids);
2485++}
2486++
2487++static void
2488++get_updates_finished_cb (GObject *object,
2489++ GAsyncResult *res,
2490++ GsdUpdatesManager *manager)
2491++{
2492++ PkClient *client = PK_CLIENT(object);
2493++ PkResults *results;
2494++ GError *error = NULL;
2495++ gboolean ret;
2496++ PkError *error_code = NULL;
2497++
2498++ /* get the results */
2499++ results = pk_client_generic_finish (PK_CLIENT(client), res, &error);
2500++ if (results == NULL) {
2501++ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
2502++ g_error_free (error);
2503++ return;
2504++ }
2505++ g_warning ("failed to get updates: %s",
2506++ error->message);
2507++ g_error_free (error);
2508++ notify_failed_get_updates_maybe (manager);
2509++ goto out;
2510++ }
2511++
2512++ /* check error code */
2513++ error_code = pk_results_get_error_code (results);
2514++ if (error_code != NULL) {
2515++ g_warning ("failed to get updates: %s, %s",
2516++ pk_error_enum_to_string (pk_error_get_code (error_code)),
2517++ pk_error_get_details (error_code));
2518++ switch (pk_error_get_code (error_code)) {
2519++ case PK_ERROR_ENUM_CANCELLED_PRIORITY:
2520++ case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
2521++ g_debug ("ignoring error");
2522++ break;
2523++ default:
2524++ notify_failed_get_updates_maybe (manager);
2525++ break;
2526++ }
2527++ goto out;
2528++ }
2529++
2530++ /* we succeeded, so clear the count */
2531++ manager->priv->failed_get_updates_count = 0;
2532++
2533++ /* so we can download or check for important & security updates */
2534++ if (manager->priv->update_packages != NULL)
2535++ g_ptr_array_unref (manager->priv->update_packages);
2536++ manager->priv->update_packages = pk_results_get_package_array (results);
2537++
2538++ /* we have no updates */
2539++ if (manager->priv->update_packages->len == 0) {
2540++ g_debug ("no updates");
2541++ goto out;
2542++ }
2543++
2544++ /* should we auto-download the updates? */
2545++ ret = g_settings_get_boolean (manager->priv->settings_gsd,
2546++ GSD_SETTINGS_AUTO_DOWNLOAD_UPDATES);
2547++ if (ret) {
2548++ auto_download_updates (manager);
2549++ goto out;
2550++ }
2551++
2552++ /* just check to see if should notify */
2553++ check_updates_for_importance (manager);
2554++out:
2555++ if (error_code != NULL)
2556++ g_object_unref (error_code);
2557++ if (results != NULL)
2558++ g_object_unref (results);
2559++}
2560++
2561++static void
2562++query_updates (GsdUpdatesManager *manager)
2563++{
2564++ /* optimize the amount of downloaded data by setting the cache age */
2565++ pk_client_set_cache_age (PK_CLIENT(manager->priv->task),
2566++ g_settings_get_int (manager->priv->settings_gsd,
2567++ GSD_SETTINGS_FREQUENCY_GET_UPDATES));
2568++
2569++ /* get new update list */
2570++ pk_client_get_updates_async (PK_CLIENT(manager->priv->task),
2571++ pk_bitfield_value (PK_FILTER_ENUM_NONE),
2572++ manager->priv->cancellable,
2573++ NULL, NULL,
2574++ (GAsyncReadyCallback) get_updates_finished_cb,
2575++ manager);
2576++}
2577++
2578++static void
2579++due_get_updates_cb (GsdUpdatesRefresh *refresh, GsdUpdatesManager *manager)
2580++{
2581++ query_updates (manager);
2582++}
2583++
2584++static gchar *
2585++get_proxy_http (GsdUpdatesManager *manager)
2586++{
2587++ gboolean ret;
2588++ gchar *host = NULL;
2589++ gchar *password = NULL;
2590++ gchar *proxy = NULL;
2591++ gchar *username = NULL;
2592++ GString *string = NULL;
2593++ guint port;
2594++ GDesktopProxyMode proxy_mode;
2595++
2596++ proxy_mode = g_settings_get_enum (manager->priv->settings_proxy, "mode");
2597++ if (proxy_mode != G_DESKTOP_PROXY_MODE_MANUAL)
2598++ goto out;
2599++
2600++ host = g_settings_get_string (manager->priv->settings_http,
2601++ "host");
2602++ if (host == NULL)
2603++ goto out;
2604++ port = g_settings_get_int (manager->priv->settings_http,
2605++ "port");
2606++
2607++ /* use an HTTP auth string? */
2608++ ret = g_settings_get_boolean (manager->priv->settings_http,
2609++ "use-authentication");
2610++ if (ret) {
2611++ username = g_settings_get_string (manager->priv->settings_http,
2612++ "authentication-user");
2613++ password = g_settings_get_string (manager->priv->settings_http,
2614++ "authentication-password");
2615++ }
2616++
2617++ /* make PackageKit proxy string */
2618++ string = g_string_new (host);
2619++ if (port > 0)
2620++ g_string_append_printf (string, ":%i", port);
2621++ if (username != NULL && password != NULL)
2622++ g_string_append_printf (string, "@%s:%s", username, password);
2623++ else if (username != NULL)
2624++ g_string_append_printf (string, "@%s", username);
2625++ else if (password != NULL)
2626++ g_string_append_printf (string, "@:%s", password);
2627++ proxy = g_string_free (string, FALSE);
2628++out:
2629++ g_free (host);
2630++ g_free (username);
2631++ g_free (password);
2632++ return proxy;
2633++}
2634++
2635++static gchar *
2636++get_proxy_ftp (GsdUpdatesManager *manager)
2637++{
2638++ gchar *host = NULL;
2639++ gchar *proxy = NULL;
2640++ GString *string = NULL;
2641++ guint port;
2642++ GDesktopProxyMode proxy_mode;
2643++
2644++ proxy_mode = g_settings_get_enum (manager->priv->settings_proxy, "mode");
2645++ if (proxy_mode != G_DESKTOP_PROXY_MODE_MANUAL)
2646++ goto out;
2647++
2648++ host = g_settings_get_string (manager->priv->settings_ftp,
2649++ "host");
2650++ if (host == NULL)
2651++ goto out;
2652++ port = g_settings_get_int (manager->priv->settings_ftp,
2653++ "port");
2654++ if (port == 0)
2655++ goto out;
2656++
2657++ /* make PackageKit proxy string */
2658++ string = g_string_new (host);
2659++ if (port > 0)
2660++ g_string_append_printf (string, ":%i", port);
2661++ proxy = g_string_free (string, FALSE);
2662++out:
2663++ g_free (host);
2664++ return proxy;
2665++}
2666++
2667++
2668++static void
2669++set_proxy_cb (GObject *object, GAsyncResult *res, gpointer user_data)
2670++{
2671++ gboolean ret;
2672++ GError *error = NULL;
2673++ PkControl *control = PK_CONTROL (object);
2674++
2675++ /* get the result */
2676++ ret = pk_control_set_proxy_finish (control, res, &error);
2677++ if (!ret) {
2678++ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
2679++ g_warning ("failed to set proxies: %s", error->message);
2680++ g_error_free (error);
2681++ }
2682++}
2683++
2684++static void
2685++reload_proxy_settings (GsdUpdatesManager *manager)
2686++{
2687++ gchar *proxy_http;
2688++ gchar *proxy_ftp;
2689++
2690++ proxy_http = get_proxy_http (manager);
2691++ proxy_ftp = get_proxy_ftp (manager);
2692++
2693++ /* send to daemon */
2694++ pk_control_set_proxy_async (manager->priv->control,
2695++ proxy_http,
2696++ proxy_ftp,
2697++ NULL,
2698++ set_proxy_cb,
2699++ manager);
2700++
2701++ g_free (proxy_http);
2702++ g_free (proxy_ftp);
2703++}
2704++
2705++static void
2706++settings_changed_cb (GSettings *settings,
2707++ const char *key,
2708++ GsdUpdatesManager *manager)
2709++{
2710++ reload_proxy_settings (manager);
2711++}
2712++
2713++static void
2714++settings_gsd_changed_cb (GSettings *settings,
2715++ const char *key,
2716++ GsdUpdatesManager *manager)
2717++{
2718++}
2719++
2720++static void
2721++session_inhibit (GsdUpdatesManager *manager)
2722++{
2723++ const gchar *reason;
2724++ GError *error = NULL;
2725++ GVariant *retval = NULL;
2726++
2727++ /* state invalid somehow */
2728++ if (manager->priv->inhibit_cookie != 0) {
2729++ g_warning ("already locked");
2730++ goto out;
2731++ }
2732++
2733++ /* TRANSLATORS: the reason why we've inhibited it */
2734++ reason = _("A transaction that cannot be interrupted is running");
2735++ retval = g_dbus_proxy_call_sync (G_DBUS_PROXY (manager->priv->proxy_session),
2736++ "Inhibit",
2737++ g_variant_new ("(susu)",
2738++ "gnome-settings-daemon", /* app-id */
2739++ 0, /* xid */
2740++ reason, /* reason */
2741++ 4 /* flags */),
2742++ G_DBUS_CALL_FLAGS_NONE,
2743++ -1,
2744++ manager->priv->cancellable,
2745++ &error);
2746++ if (retval == NULL) {
2747++ g_warning ("failed to inhibit gnome-session: %s",
2748++ error->message);
2749++ g_error_free (error);
2750++ goto out;
2751++ }
2752++
2753++ /* get cookie */
2754++ g_variant_get (retval, "(u)",
2755++ &manager->priv->inhibit_cookie);
2756++out:
2757++ if (retval != NULL)
2758++ g_variant_unref (retval);
2759++}
2760++
2761++static void
2762++session_uninhibit (GsdUpdatesManager *manager)
2763++{
2764++ GError *error = NULL;
2765++ GVariant *retval = NULL;
2766++
2767++ /* state invalid somehow */
2768++ if (manager->priv->inhibit_cookie == 0) {
2769++ g_warning ("not locked");
2770++ goto out;
2771++ }
2772++ retval = g_dbus_proxy_call_sync (G_DBUS_PROXY (manager->priv->proxy_session),
2773++ "Uninhibit",
2774++ g_variant_new ("(u)",
2775++ manager->priv->inhibit_cookie),
2776++ G_DBUS_CALL_FLAGS_NONE,
2777++ -1,
2778++ manager->priv->cancellable,
2779++ &error);
2780++ if (retval == NULL) {
2781++ g_warning ("failed to uninhibit gnome-session: %s",
2782++ error->message);
2783++ g_error_free (error);
2784++ goto out;
2785++ }
2786++out:
2787++ manager->priv->inhibit_cookie = 0;
2788++ if (retval != NULL)
2789++ g_variant_unref (retval);
2790++}
2791++
2792++static void
2793++notify_locked_cb (PkControl *control,
2794++ GParamSpec *pspec,
2795++ GsdUpdatesManager *manager)
2796++{
2797++ gboolean locked;
2798++
2799++ g_object_get (control, "locked", &locked, NULL);
2800++
2801++ /* TODO: locked is a bit harsh, we can probably still allow
2802++ * reboot when packages are downloading or the transaction is
2803++ * depsolving */
2804++ if (locked) {
2805++ session_inhibit (manager);
2806++ } else {
2807++ session_uninhibit (manager);
2808++ }
2809++}
2810++
2811++static void
2812++update_viewer_appeared_cb (GDBusConnection *connection,
2813++ const gchar *name,
2814++ const gchar *name_owner,
2815++ gpointer user_data)
2816++{
2817++ GsdUpdatesManager *manager = GSD_UPDATES_MANAGER (user_data);
2818++
2819++ /* close any existing notification */
2820++ if (manager->priv->notification_updates != NULL) {
2821++ g_debug ("update viewer on the bus, clearing bubble");
2822++ notify_notification_close (manager->priv->notification_updates, NULL);
2823++ manager->priv->notification_updates = NULL;
2824++ }
2825++}
2826++
2827++static gboolean
2828++file_exists_in_root (const gchar *root, const gchar *filename)
2829++{
2830++ gboolean ret = FALSE;
2831++ GFile *source;
2832++ gchar *source_path;
2833++
2834++ source_path = g_build_filename (root, filename, NULL);
2835++ source = g_file_new_for_path (source_path);
2836++
2837++ /* ignore virtual mountpoints */
2838++ if (!g_file_is_native (source))
2839++ goto out;
2840++
2841++ /* an interesting file exists */
2842++ ret = g_file_query_exists (source, NULL);
2843++ g_debug ("checking for %s: %s", source_path, ret ? "yes" : "no");
2844++ if (!ret)
2845++ goto out;
2846++out:
2847++ g_free (source_path);
2848++ g_object_unref (source);
2849++ return ret;
2850++}
2851++
2852++static void
2853++mount_added_cb (GVolumeMonitor *volume_monitor,
2854++ GMount *mount,
2855++ GsdUpdatesManager *manager)
2856++{
2857++ gboolean ret = FALSE;
2858++ gchar **filenames = NULL;
2859++ gchar *media_repo_filenames;
2860++ gchar *root_path;
2861++ GFile *root;
2862++ guint i;
2863++
2864++ /* check if any installed media is an install disk */
2865++ root = g_mount_get_root (mount);
2866++ root_path = g_file_get_path (root);
2867++
2868++ /* use settings */
2869++ media_repo_filenames = g_settings_get_string (manager->priv->settings_gsd,
2870++ GSD_SETTINGS_MEDIA_REPO_FILENAMES);
2871++ if (media_repo_filenames == NULL) {
2872++ g_warning ("failed to get media repo filenames");
2873++ goto out;
2874++ }
2875++
2876++ /* search each possible filename */
2877++ filenames = g_strsplit (media_repo_filenames, ",", -1);
2878++ for (i=0; filenames[i] != NULL; i++) {
2879++ ret = file_exists_in_root (root_path, filenames[i]);
2880++ if (ret)
2881++ break;
2882++ }
2883++
2884++ /* do an updates check with the new media */
2885++ if (ret)
2886++ query_updates (manager);
2887++out:
2888++ g_strfreev (filenames);
2889++ g_free (media_repo_filenames);
2890++ g_free (root_path);
2891++ g_object_unref (root);
2892++}
2893++
2894++#define PK_OFFLINE_UPDATE_RESULTS_GROUP "PackageKit Offline Update Results"
2895++#define PK_OFFLINE_UPDATE_RESULTS_FILENAME "/var/lib/PackageKit/offline-update-competed"
2896++
2897++static gboolean
2898++check_offline_update_cb (gpointer user_data)
2899++{
2900++ const gchar *message;
2901++ const gchar *title;
2902++ gboolean ret;
2903++ gboolean success;
2904++ gchar *error_code = NULL;
2905++ gchar *error_details = NULL;
2906++ gchar *packages = NULL;
2907++ GError *error = NULL;
2908++ GKeyFile *key_file = NULL;
2909++ GsdUpdatesManager *manager = (GsdUpdatesManager *) user_data;
2910++ guint i;
2911++ guint num_packages = 1;
2912++ NotifyNotification *notification;
2913++ PkErrorEnum error_enum = PK_ERROR_ENUM_UNKNOWN;
2914++
2915++ /* was any offline update attempted */
2916++ if (!g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS))
2917++ goto out;
2918++
2919++ /* open the file and see what happened */
2920++ key_file = g_key_file_new ();
2921++ ret = g_key_file_load_from_file (key_file,
2922++ PK_OFFLINE_UPDATE_RESULTS_FILENAME,
2923++ G_KEY_FILE_NONE,
2924++ &error);
2925++ if (!ret) {
2926++ g_warning ("failed to open %s: %s",
2927++ PK_OFFLINE_UPDATE_RESULTS_FILENAME,
2928++ error->message);
2929++ g_error_free (error);
2930++ goto out;
2931++ }
2932++ success = g_key_file_get_boolean (key_file,
2933++ PK_OFFLINE_UPDATE_RESULTS_GROUP,
2934++ "Success",
2935++ NULL);
2936++ if (success) {
2937++ packages = g_key_file_get_string (key_file,
2938++ PK_OFFLINE_UPDATE_RESULTS_GROUP,
2939++ "Packages",
2940++ NULL);
2941++ if (packages == NULL) {
2942++ g_warning ("No 'Packages' in %s",
2943++ PK_OFFLINE_UPDATE_RESULTS_FILENAME);
2944++ goto out;
2945++ }
2946++
2947++ /* count the packages for translators */
2948++ for (i = 0; packages[i] != '\0'; i++) {
2949++ if (packages[i] == ',')
2950++ num_packages++;
2951++ }
2952++
2953++ /* TRANSLATORS: title in the libnotify popup */
2954++ title = ngettext ("Software Update Installed",
2955++ "Software Updates Installed",
2956++ num_packages);
2957++
2958++ /* TRANSLATORS: message when we've done offline updates */
2959++ message = ngettext ("An important OS update has been installed.",
2960++ "Important OS updates have been installed.",
2961++ num_packages);
2962++ } else {
2963++ /* get error details */
2964++ manager->priv->offline_update_error = pk_error_new ();
2965++
2966++ error_code = g_key_file_get_string (key_file,
2967++ PK_OFFLINE_UPDATE_RESULTS_GROUP,
2968++ "ErrorCode",
2969++ NULL);
2970++ if (error_code != NULL)
2971++ error_enum = pk_error_enum_from_string (error_code);
2972++ error_details = g_key_file_get_string (key_file,
2973++ PK_OFFLINE_UPDATE_RESULTS_GROUP,
2974++ "ErrorDetails",
2975++ NULL);
2976++ g_object_set (manager->priv->offline_update_error,
2977++ "code", error_enum,
2978++ "details", error_details,
2979++ NULL);
2980++
2981++ /* TRANSLATORS: title in the libnotify popup */
2982++ title = _("Software Updates Failed");
2983++
2984++ /* TRANSLATORS: message when we've not done offline updates */
2985++ message = _("An important OS update failed to be installed.");
2986++ }
2987++
2988++ /* do the bubble */
2989++ g_debug ("title=%s, message=%s", title, message);
2990++
2991++ /* close any existing notification */
2992++ if (manager->priv->notification_offline_success != NULL) {
2993++ notify_notification_close (manager->priv->notification_offline_success, NULL);
2994++ manager->priv->notification_offline_success = NULL;
2995++ }
2996++
2997++ notification = notify_notification_new (title,
2998++ message,
2999++ GSD_UPDATES_ICON_URGENT);
3000++ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-update-viewer");
3001++ notify_notification_set_app_name (notification, _("Software Updates"));
3002++ notify_notification_set_timeout (notification, -1);
3003++ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
3004++ if (!success) {
3005++ notify_notification_add_action (notification, "error-offline-updates",
3006++ /* TRANSLATORS: button: review the offline update changes */
3007++ _("Show details"), libnotify_action_cb, manager, NULL);
3008++ }
3009++ notify_notification_add_action (notification, "clear-offline-updates",
3010++ /* TRANSLATORS: button: clear notification */
3011++ _("OK"), libnotify_action_cb, manager, NULL);
3012++ g_signal_connect (notification, "closed",
3013++ G_CALLBACK (on_notification_closed), NULL);
3014++ manager->priv->notification_offline_success = notification;
3015++ g_object_add_weak_pointer (G_OBJECT (manager->priv->notification_offline_success),
3016++ (void **) &manager->priv->notification_offline_success);
3017++ ret = notify_notification_show (notification, &error);
3018++ if (!ret) {
3019++ g_warning ("error: %s", error->message);
3020++ g_error_free (error);
3021++ }
3022++out:
3023++ g_free (packages);
3024++ g_free (error_code);
3025++ g_free (error_details);
3026++ if (key_file != NULL)
3027++ g_key_file_free (key_file);
3028++ manager->priv->offline_update_id = 0;
3029++ return FALSE;
3030++}
3031++
3032++static void
3033++reboot_failed (GObject *source, GAsyncResult *res, gpointer data)
3034++{
3035++ GVariant *ret;
3036++ const gchar *command;
3037++ GError *error = NULL;
3038++
3039++ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
3040++ if (ret) {
3041++ g_variant_unref (ret);
3042++ return;
3043++ }
3044++
3045++ if (error) {
3046++ g_warning ("Calling org.gnome.SessionManager.Reboot failed: %s\n", error->message);
3047++ g_error_free (error);
3048++ return;
3049++ }
3050++
3051++ command = "pkexec /usr/libexec/pk-trigger-offline-update --cancel";
3052++ g_debug ("calling '%s'", command);
3053++ if (!g_spawn_command_line_sync (command, NULL, NULL, NULL, &error)) {
3054++ g_warning ("Failed to call '%s': %s\n", command, error->message);
3055++ g_error_free (error);
3056++ }
3057++}
3058++
3059++static void
3060++restart_and_install_updates (void)
3061++{
3062++ GDBusConnection *bus;
3063++ const gchar *command;
3064++ GError *error = NULL;
3065++
3066++ command = "pkexec /usr/libexec/pk-trigger-offline-update";
3067++ g_debug ("calling '%s'", command);
3068++ if (!g_spawn_command_line_sync (command, NULL, NULL, NULL, &error)) {
3069++ g_warning ("Failed to call '%s': %s\n", command, error->message);
3070++ g_error_free (error);
3071++ return;
3072++ }
3073++
3074++ g_debug ("calling org.gnome.SessionManager.Reboot");
3075++ bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
3076++ g_dbus_connection_call (bus,
3077++ "org.gnome.SessionManager",
3078++ "/org/gnome/SessionManager",
3079++ "org.gnome.SessionManager",
3080++ "Reboot",
3081++ NULL,
3082++ NULL,
3083++ G_DBUS_CALL_FLAGS_NONE,
3084++ G_MAXINT,
3085++ NULL,
3086++ reboot_failed,
3087++ NULL);
3088++ g_object_unref (bus);
3089++}
3090++
3091++gboolean
3092++gsd_updates_manager_start (GsdUpdatesManager *manager,
3093++ GError **error)
3094++{
3095++ gboolean ret = FALSE;
3096++
3097++ g_debug ("Starting updates manager");
3098++
3099++ /* use PackageKit */
3100++ manager->priv->cancellable = g_cancellable_new ();
3101++ manager->priv->control = pk_control_new ();
3102++ g_signal_connect (manager->priv->control, "notify::locked",
3103++ G_CALLBACK (notify_locked_cb), manager);
3104++ manager->priv->task = pk_task_new ();
3105++ g_object_set (manager->priv->task,
3106++ "background", TRUE,
3107++ "interactive", FALSE,
3108++ "only-download", TRUE,
3109++ NULL);
3110++
3111++ /* watch UDev for missing firmware */
3112++ manager->priv->firmware = gsd_updates_firmware_new ();
3113++
3114++ /* get automatic callbacks about when we should check for
3115++ * updates, refresh-caches and upgrades */
3116++ manager->priv->refresh = gsd_updates_refresh_new ();
3117++ g_signal_connect (manager->priv->refresh, "get-upgrades",
3118++ G_CALLBACK (due_get_upgrades_cb), manager);
3119++ g_signal_connect (manager->priv->refresh, "refresh-cache",
3120++ G_CALLBACK (due_refresh_cache_cb), manager);
3121++ /* gnome-software takes over software updates if it's installed */
3122++ if (!does_gnome_software_exist ()) {
3123++ g_signal_connect (manager->priv->refresh, "get-updates",
3124++ G_CALLBACK (due_get_updates_cb), manager);
3125++ }
3126++
3127++ /* get proxy settings */
3128++ manager->priv->settings_proxy = g_settings_new ("org.gnome.system.proxy");
3129++ g_signal_connect (manager->priv->settings_proxy, "changed",
3130++ G_CALLBACK (settings_changed_cb), manager);
3131++
3132++ /* get http settings */
3133++ manager->priv->settings_http = g_settings_new ("org.gnome.system.proxy.http");
3134++ g_signal_connect (manager->priv->settings_http, "changed",
3135++ G_CALLBACK (settings_changed_cb), manager);
3136++
3137++ /* get ftp settings */
3138++ manager->priv->settings_ftp = g_settings_new ("org.gnome.system.proxy.ftp");
3139++ g_signal_connect (manager->priv->settings_ftp, "changed",
3140++ G_CALLBACK (settings_changed_cb), manager);
3141++
3142++ /* get ftp settings */
3143++ manager->priv->settings_gsd = g_settings_new ("org.gnome.settings-daemon.plugins.updates");
3144++ g_signal_connect (manager->priv->settings_gsd, "changed",
3145++ G_CALLBACK (settings_gsd_changed_cb), manager);
3146++
3147++ /* use gnome-session for the idle detection */
3148++ manager->priv->proxy_session =
3149++ gnome_settings_bus_get_session_proxy ();
3150++ if (manager->priv->proxy_session == NULL)
3151++ goto out;
3152++
3153++ /* if the update viewer is started, then hide the notification */
3154++ manager->priv->update_viewer_watcher_id =
3155++ g_bus_watch_name (G_BUS_TYPE_SESSION,
3156++ "org.freedesktop.PackageKit.UpdateViewer",
3157++ G_BUS_NAME_WATCHER_FLAGS_NONE,
3158++ update_viewer_appeared_cb,
3159++ NULL,
3160++ manager,
3161++ NULL);
3162++
3163++ /* get a volume monitor so we can watch media */
3164++ manager->priv->volume_monitor = g_volume_monitor_get ();
3165++ g_signal_connect (manager->priv->volume_monitor, "mount-added",
3166++ G_CALLBACK (mount_added_cb), manager);
3167++
3168++ /* coldplug */
3169++ reload_proxy_settings (manager);
3170++
3171++ /* check for offline update */
3172++ if (!does_gnome_software_exist ()) {
3173++ manager->priv->offline_update_id =
3174++ g_timeout_add_seconds (GSD_UPDATES_CHECK_OFFLINE_TIMEOUT,
3175++ check_offline_update_cb,
3176++ manager);
3177++ }
3178++
3179++ /* success */
3180++ ret = TRUE;
3181++ g_debug ("Started updates manager");
3182++out:
3183++ return ret;
3184++}
3185++
3186++void
3187++gsd_updates_manager_stop (GsdUpdatesManager *manager)
3188++{
3189++ g_debug ("Stopping updates manager");
3190++
3191++ g_clear_object (&manager->priv->settings_proxy);
3192++ g_clear_object (&manager->priv->settings_http);
3193++ g_clear_object (&manager->priv->settings_ftp);
3194++ g_clear_object (&manager->priv->settings_gsd);
3195++ g_clear_object (&manager->priv->control);
3196++ g_clear_object (&manager->priv->task);
3197++ g_clear_object (&manager->priv->refresh);
3198++ g_clear_object (&manager->priv->firmware);
3199++ g_clear_object (&manager->priv->proxy_session);
3200++ g_clear_object (&manager->priv->volume_monitor);
3201++ if (manager->priv->cancellable) {
3202++ g_cancellable_cancel (manager->priv->cancellable);
3203++ g_clear_object (&manager->priv->cancellable);
3204++ }
3205++ if (manager->priv->update_viewer_watcher_id != 0) {
3206++ g_bus_unwatch_name (manager->priv->update_viewer_watcher_id);
3207++ manager->priv->update_viewer_watcher_id = 0;
3208++ }
3209++ if (manager->priv->offline_update_id) {
3210++ g_source_remove (manager->priv->offline_update_id);
3211++ manager->priv->offline_update_id = 0;
3212++ }
3213++ if (manager->priv->update_packages != NULL) {
3214++ g_ptr_array_unref (manager->priv->update_packages);
3215++ manager->priv->update_packages = NULL;
3216++ }
3217++ g_clear_object (&manager->priv->offline_update_error);
3218++}
3219++
3220++static void
3221++gsd_updates_manager_dispose (GObject *object)
3222++{
3223++ GsdUpdatesManager *manager;
3224++
3225++ manager = GSD_UPDATES_MANAGER (object);
3226++
3227++ gsd_updates_manager_stop (manager);
3228++
3229++ G_OBJECT_CLASS (gsd_updates_manager_parent_class)->dispose (object);
3230++}
3231++
3232++static void
3233++gsd_updates_manager_class_init (GsdUpdatesManagerClass *klass)
3234++{
3235++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
3236++
3237++ object_class->dispose = gsd_updates_manager_dispose;
3238++
3239++ g_type_class_add_private (klass, sizeof (GsdUpdatesManagerPrivate));
3240++}
3241++
3242++static void
3243++gsd_updates_manager_init (GsdUpdatesManager *manager)
3244++{
3245++ manager->priv = GSD_UPDATES_MANAGER_GET_PRIVATE (manager);
3246++}
3247++
3248++GsdUpdatesManager *
3249++gsd_updates_manager_new (void)
3250++{
3251++ if (manager_object) {
3252++ g_object_ref (manager_object);
3253++ } else {
3254++ manager_object = g_object_new (GSD_TYPE_UPDATES_MANAGER, NULL);
3255++ g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object);
3256++ }
3257++
3258++ return GSD_UPDATES_MANAGER (manager_object);
3259++}
3260+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-manager.h
3261+===================================================================
3262+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3263++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-manager.h 2014-12-02 00:06:35.441485533 +0100
3264+@@ -0,0 +1,56 @@
3265++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3266++ *
3267++ * Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
3268++ *
3269++ * This program is free software; you can redistribute it and/or modify
3270++ * it under the terms of the GNU General Public License as published by
3271++ * the Free Software Foundation; either version 2 of the License, or
3272++ * (at your option) any later version.
3273++ *
3274++ * This program is distributed in the hope that it will be useful,
3275++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3276++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3277++ * GNU General Public License for more details.
3278++ *
3279++ * You should have received a copy of the GNU General Public License
3280++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
3281++ *
3282++ */
3283++
3284++#ifndef __GSD_UPDATES_MANAGER_H
3285++#define __GSD_UPDATES_MANAGER_H
3286++
3287++#include <glib.h>
3288++#include <glib-object.h>
3289++
3290++G_BEGIN_DECLS
3291++
3292++#define GSD_TYPE_UPDATES_MANAGER (gsd_updates_manager_get_type ())
3293++#define GSD_UPDATES_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_UPDATES_MANAGER, GsdUpdatesManager))
3294++#define GSD_UPDATES_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSD_TYPE_UPDATES_MANAGER, GsdUpdatesManagerClass))
3295++#define GSD_IS_UPDATES_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_UPDATES_MANAGER))
3296++#define GSD_IS_UPDATES_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_UPDATES_MANAGER))
3297++#define GSD_UPDATES_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_UPDATES_MANAGER, GsdUpdatesManagerClass))
3298++
3299++typedef struct GsdUpdatesManagerPrivate GsdUpdatesManagerPrivate;
3300++
3301++typedef struct
3302++{
3303++ GObject parent;
3304++ GsdUpdatesManagerPrivate *priv;
3305++} GsdUpdatesManager;
3306++
3307++typedef struct
3308++{
3309++ GObjectClass parent_class;
3310++} GsdUpdatesManagerClass;
3311++
3312++GType gsd_updates_manager_get_type (void) G_GNUC_CONST;
3313++
3314++GsdUpdatesManager *gsd_updates_manager_new (void);
3315++gboolean gsd_updates_manager_start (GsdUpdatesManager *manager, GError **error);
3316++void gsd_updates_manager_stop (GsdUpdatesManager *manager);
3317++
3318++G_END_DECLS
3319++
3320++#endif /* __GSD_UPDATES_MANAGER_H */
3321+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-plugin.c
3322+===================================================================
3323+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3324++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-plugin.c 2014-12-02 00:06:35.441485533 +0100
3325+@@ -0,0 +1,28 @@
3326++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3327++ *
3328++ * Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
3329++ *
3330++ * This program is free software; you can redistribute it and/or modify
3331++ * it under the terms of the GNU General Public License as published by
3332++ * the Free Software Foundation; either version 2, or (at your option)
3333++ * any later version.
3334++ *
3335++ * This program is distributed in the hope that it will be useful,
3336++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3337++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3338++ * GNU General Public License for more details.
3339++ *
3340++ * You should have received a copy of the GNU General Public License
3341++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
3342++ *
3343++ */
3344++
3345++#include "config.h"
3346++
3347++#include <glib/gi18n-lib.h>
3348++#include <gmodule.h>
3349++
3350++#include "gnome-settings-plugin.h"
3351++#include "gsd-updates-manager.h"
3352++
3353++GNOME_SETTINGS_PLUGIN_REGISTER (GsdUpdates, gsd_updates)
3354+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-refresh.c
3355+===================================================================
3356+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3357++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-refresh.c 2014-12-02 00:07:17.324863126 +0100
3358+@@ -0,0 +1,575 @@
3359++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3360++ *
3361++ * Copyright (C) 2007-2011 Richard Hughes <richard@hughsie.com>
3362++ *
3363++ * Licensed under the GNU General Public License Version 2
3364++ *
3365++ * This program is free software; you can redistribute it and/or modify
3366++ * it under the terms of the GNU General Public License as published by
3367++ * the Free Software Foundation; either version 2 of the License, or
3368++ * (at your option) any later version.
3369++ *
3370++ * This program is distributed in the hope that it will be useful,
3371++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3372++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3373++ * GNU General Public License for more details.
3374++ *
3375++ * You should have received a copy of the GNU General Public License
3376++ * along with this program; if not, write to the Free Software
3377++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3378++ */
3379++
3380++#include "config.h"
3381++
3382++#include <glib/gi18n.h>
3383++#include <packagekit-glib2/packagekit.h>
3384++#include <libupower-glib/upower.h>
3385++
3386++#include "gnome-settings-bus.h"
3387++
3388++#include "gsd-updates-common.h"
3389++#include "gsd-updates-refresh.h"
3390++
3391++static void gsd_updates_refresh_finalize (GObject *object);
3392++
3393++#define GSD_UPDATES_REFRESH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_UPDATES_REFRESH, GsdUpdatesRefreshPrivate))
3394++
3395++#define PERIODIC_CHECK_TIME 60*60 /* poke PackageKit every hour */
3396++#define LOGIN_TIMEOUT 3 /* seconds */
3397++#define SESSION_STARTUP_TIMEOUT 10 /* seconds */
3398++
3399++enum {
3400++ PRESENCE_STATUS_AVAILABLE = 0,
3401++ PRESENCE_STATUS_INVISIBLE,
3402++ PRESENCE_STATUS_BUSY,
3403++ PRESENCE_STATUS_IDLE,
3404++ PRESENCE_STATUS_UNKNOWN
3405++};
3406++
3407++/*
3408++ * at startup, after a small delay, force a GetUpdates call
3409++ * every hour (or any event) check:
3410++ - if we are online, idle and on AC power, it's been more than a day
3411++ since we refreshed then RefreshCache
3412++ - if we are online and it's been longer than the timeout since
3413++ getting the updates period then GetUpdates
3414++*/
3415++
3416++struct GsdUpdatesRefreshPrivate
3417++{
3418++ gboolean session_idle;
3419++ gboolean on_battery;
3420++ gboolean network_active;
3421++ guint timeout_id;
3422++ guint periodic_id;
3423++ UpClient *client;
3424++ GSettings *settings;
3425++ GsdSessionManager *proxy_session;
3426++ PkControl *control;
3427++};
3428++
3429++enum {
3430++ REFRESH_CACHE,
3431++ GET_UPDATES,
3432++ GET_UPGRADES,
3433++ LAST_SIGNAL
3434++};
3435++
3436++static guint signals [LAST_SIGNAL] = { 0 };
3437++
3438++G_DEFINE_TYPE (GsdUpdatesRefresh, gsd_updates_refresh, G_TYPE_OBJECT)
3439++
3440++static void
3441++gsd_updates_refresh_class_init (GsdUpdatesRefreshClass *klass)
3442++{
3443++ GObjectClass *object_class = G_OBJECT_CLASS (klass);
3444++ object_class->finalize = gsd_updates_refresh_finalize;
3445++ g_type_class_add_private (klass, sizeof (GsdUpdatesRefreshPrivate));
3446++ signals [REFRESH_CACHE] =
3447++ g_signal_new ("refresh-cache",
3448++ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
3449++ 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
3450++ G_TYPE_NONE, 0);
3451++ signals [GET_UPDATES] =
3452++ g_signal_new ("get-updates",
3453++ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
3454++ 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
3455++ G_TYPE_NONE, 0);
3456++ signals [GET_UPGRADES] =
3457++ g_signal_new ("get-upgrades",
3458++ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
3459++ 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
3460++ G_TYPE_NONE, 0);
3461++}
3462++
3463++static void
3464++get_time_refresh_cache_cb (GObject *object,
3465++ GAsyncResult *res,
3466++ GsdUpdatesRefresh *refresh)
3467++{
3468++ PkControl *control = PK_CONTROL (object);
3469++ GError *error = NULL;
3470++ guint seconds;
3471++ guint thresh;
3472++
3473++ /* get the result */
3474++ seconds = pk_control_get_time_since_action_finish (control, res, &error);
3475++ if (seconds == 0) {
3476++ g_warning ("failed to get time: %s", error->message);
3477++ g_error_free (error);
3478++ return;
3479++ }
3480++
3481++ /* have we passed the timout? */
3482++ thresh = g_settings_get_int (refresh->priv->settings,
3483++ GSD_SETTINGS_FREQUENCY_GET_UPDATES);
3484++ if (seconds < thresh) {
3485++ g_debug ("not before timeout, thresh=%u, now=%u", thresh, seconds);
3486++ return;
3487++ }
3488++
3489++ /* send signal */
3490++ g_debug ("emitting refresh-cache");
3491++ g_signal_emit (refresh, signals [REFRESH_CACHE], 0);
3492++}
3493++
3494++static void
3495++maybe_refresh_cache (GsdUpdatesRefresh *refresh)
3496++{
3497++ guint thresh;
3498++
3499++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3500++
3501++ /* if we don't want to auto check for updates, don't do this either */
3502++ thresh = g_settings_get_int (refresh->priv->settings,
3503++ GSD_SETTINGS_FREQUENCY_GET_UPDATES);
3504++ if (thresh == 0) {
3505++ g_debug ("not when policy is set to never");
3506++ return;
3507++ }
3508++
3509++ /* only do the refresh cache when the user is idle */
3510++ if (!refresh->priv->session_idle) {
3511++ g_debug ("not when session active");
3512++ return;
3513++ }
3514++
3515++ /* get this each time, as it may have changed behind out back */
3516++ thresh = g_settings_get_int (refresh->priv->settings,
3517++ GSD_SETTINGS_FREQUENCY_REFRESH_CACHE);
3518++ if (thresh == 0) {
3519++ g_debug ("not when policy is set to never");
3520++ return;
3521++ }
3522++
3523++ /* get the time since the last refresh */
3524++ pk_control_get_time_since_action_async (refresh->priv->control,
3525++ PK_ROLE_ENUM_REFRESH_CACHE,
3526++ NULL,
3527++ (GAsyncReadyCallback) get_time_refresh_cache_cb,
3528++ refresh);
3529++}
3530++
3531++static void
3532++get_time_get_updates_cb (GObject *object, GAsyncResult *res, GsdUpdatesRefresh *refresh)
3533++{
3534++ PkControl *control = PK_CONTROL (object);
3535++ GError *error = NULL;
3536++ guint seconds;
3537++ guint thresh;
3538++
3539++ /* get the result */
3540++ seconds = pk_control_get_time_since_action_finish (control, res, &error);
3541++ if (seconds == 0) {
3542++ g_warning ("failed to get time: %s", error->message);
3543++ g_error_free (error);
3544++ return;
3545++ }
3546++
3547++ /* have we passed the timout? */
3548++ thresh = g_settings_get_int (refresh->priv->settings,
3549++ GSD_SETTINGS_FREQUENCY_GET_UPDATES);
3550++ if (seconds < thresh) {
3551++ g_debug ("not before timeout, thresh=%u, now=%u", thresh, seconds);
3552++ return;
3553++ }
3554++
3555++ /* send signal */
3556++ g_debug ("emitting get-updates");
3557++ g_signal_emit (refresh, signals [GET_UPDATES], 0);
3558++}
3559++
3560++static void
3561++maybe_get_updates (GsdUpdatesRefresh *refresh)
3562++{
3563++ guint thresh;
3564++
3565++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3566++
3567++ /* if we don't want to auto check for updates, don't do this either */
3568++ thresh = g_settings_get_int (refresh->priv->settings,
3569++ GSD_SETTINGS_FREQUENCY_GET_UPDATES);
3570++ if (thresh == 0) {
3571++ g_debug ("not when policy is set to never");
3572++ return;
3573++ }
3574++
3575++ /* get the time since the last refresh */
3576++ pk_control_get_time_since_action_async (refresh->priv->control,
3577++ PK_ROLE_ENUM_GET_UPDATES,
3578++ NULL,
3579++ (GAsyncReadyCallback) get_time_get_updates_cb,
3580++ refresh);
3581++}
3582++
3583++static void
3584++get_time_get_upgrades_cb (GObject *object,
3585++ GAsyncResult *res,
3586++ GsdUpdatesRefresh *refresh)
3587++{
3588++ PkControl *control = PK_CONTROL (object);
3589++ GError *error = NULL;
3590++ guint seconds;
3591++ guint thresh;
3592++
3593++ /* get the result */
3594++ seconds = pk_control_get_time_since_action_finish (control, res, &error);
3595++ if (seconds == 0) {
3596++ g_warning ("failed to get time: %s", error->message);
3597++ g_error_free (error);
3598++ return;
3599++ }
3600++
3601++ /* have we passed the timout? */
3602++ thresh = g_settings_get_int (refresh->priv->settings,
3603++ GSD_SETTINGS_FREQUENCY_GET_UPDATES);
3604++ if (seconds < thresh) {
3605++ g_debug ("not before timeout, thresh=%u, now=%u",
3606++ thresh, seconds);
3607++ return;
3608++ }
3609++
3610++ /* send signal */
3611++ g_debug ("emitting get-upgrades");
3612++ g_signal_emit (refresh, signals [GET_UPGRADES], 0);
3613++}
3614++
3615++static void
3616++maybe_get_upgrades (GsdUpdatesRefresh *refresh)
3617++{
3618++ guint thresh;
3619++
3620++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3621++
3622++ /* get this each time, as it may have changed behind out back */
3623++ thresh = g_settings_get_int (refresh->priv->settings,
3624++ GSD_SETTINGS_FREQUENCY_GET_UPGRADES);
3625++ if (thresh == 0) {
3626++ g_debug ("not when policy is set to never");
3627++ return;
3628++ }
3629++
3630++ /* get the time since the last refresh */
3631++ pk_control_get_time_since_action_async (refresh->priv->control,
3632++ PK_ROLE_ENUM_GET_DISTRO_UPGRADES,
3633++ NULL,
3634++ (GAsyncReadyCallback) get_time_get_upgrades_cb,
3635++ refresh);
3636++}
3637++
3638++static gboolean
3639++change_state_cb (GsdUpdatesRefresh *refresh)
3640++{
3641++ /* check all actions */
3642++ maybe_refresh_cache (refresh);
3643++ maybe_get_updates (refresh);
3644++ maybe_get_upgrades (refresh);
3645++ return FALSE;
3646++}
3647++
3648++static gboolean
3649++change_state (GsdUpdatesRefresh *refresh)
3650++{
3651++ gboolean ret;
3652++
3653++ g_return_val_if_fail (GSD_IS_UPDATES_REFRESH (refresh), FALSE);
3654++
3655++ /* no point continuing if we have no network */
3656++ if (!refresh->priv->network_active) {
3657++ g_debug ("not when no network");
3658++ refresh->priv->timeout_id = 0;
3659++ return FALSE;
3660++ }
3661++
3662++ /* not on battery unless overridden */
3663++ ret = g_settings_get_boolean (refresh->priv->settings,
3664++ GSD_SETTINGS_UPDATE_BATTERY);
3665++ if (!ret && refresh->priv->on_battery) {
3666++ g_debug ("not when on battery");
3667++ refresh->priv->timeout_id = 0;
3668++ return FALSE;
3669++ }
3670++
3671++ /* wait a little time for things to settle down */
3672++ if (refresh->priv->timeout_id != 0)
3673++ g_source_remove (refresh->priv->timeout_id);
3674++ g_debug ("defering action for %i seconds",
3675++ SESSION_STARTUP_TIMEOUT);
3676++ refresh->priv->timeout_id =
3677++ g_timeout_add_seconds (SESSION_STARTUP_TIMEOUT,
3678++ (GSourceFunc) change_state_cb,
3679++ refresh);
3680++ g_source_set_name_by_id (refresh->priv->timeout_id,
3681++ "[GsdUpdatesRefresh] change-state");
3682++
3683++ return TRUE;
3684++}
3685++
3686++static void
3687++settings_key_changed_cb (GSettings *client,
3688++ const gchar *key,
3689++ GsdUpdatesRefresh *refresh)
3690++{
3691++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3692++ if (g_strcmp0 (key, GSD_SETTINGS_FREQUENCY_GET_UPDATES) == 0 ||
3693++ g_strcmp0 (key, GSD_SETTINGS_FREQUENCY_GET_UPGRADES) == 0 ||
3694++ g_strcmp0 (key, GSD_SETTINGS_FREQUENCY_REFRESH_CACHE) == 0 ||
3695++ g_strcmp0 (key, GSD_SETTINGS_UPDATE_BATTERY) == 0)
3696++ change_state (refresh);
3697++}
3698++
3699++static gboolean
3700++convert_network_state (GsdUpdatesRefresh *refresh, PkNetworkEnum state)
3701++{
3702++ /* offline */
3703++ if (state == PK_NETWORK_ENUM_OFFLINE)
3704++ return FALSE;
3705++
3706++ /* online */
3707++ if (state == PK_NETWORK_ENUM_ONLINE ||
3708++ state == PK_NETWORK_ENUM_WIFI ||
3709++ state == PK_NETWORK_ENUM_WIRED)
3710++ return TRUE;
3711++
3712++ /* check policy */
3713++ if (state == PK_NETWORK_ENUM_MOBILE)
3714++ return g_settings_get_boolean (refresh->priv->settings,
3715++ GSD_SETTINGS_CONNECTION_USE_MOBILE);
3716++
3717++ /* not recognised */
3718++ g_warning ("state unknown: %i", state);
3719++ return TRUE;
3720++}
3721++
3722++static void
3723++notify_network_state_cb (PkControl *control,
3724++ GParamSpec *pspec,
3725++ GsdUpdatesRefresh *refresh)
3726++{
3727++ PkNetworkEnum state;
3728++
3729++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3730++
3731++ g_object_get (control, "network-state", &state, NULL);
3732++ refresh->priv->network_active = convert_network_state (refresh, state);
3733++ g_debug ("setting online %i", refresh->priv->network_active);
3734++ if (refresh->priv->network_active)
3735++ change_state (refresh);
3736++}
3737++
3738++static gboolean
3739++periodic_timeout_cb (gpointer user_data)
3740++{
3741++ GsdUpdatesRefresh *refresh = GSD_UPDATES_REFRESH (user_data);
3742++
3743++ g_return_val_if_fail (GSD_IS_UPDATES_REFRESH (refresh), FALSE);
3744++
3745++ /* debug so we can catch polling */
3746++ g_debug ("polling check");
3747++
3748++ /* triggered once an hour */
3749++ change_state (refresh);
3750++
3751++ /* always return */
3752++ return TRUE;
3753++}
3754++
3755++static void
3756++gsd_updates_refresh_client_on_battery_cb (UpClient *client,
3757++ GParamSpec *pspec,
3758++ GsdUpdatesRefresh *refresh)
3759++{
3760++ gboolean on_battery;
3761++
3762++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3763++
3764++ /* get the on-battery state */
3765++ on_battery = up_client_get_on_battery (refresh->priv->client);
3766++ if (on_battery == refresh->priv->on_battery) {
3767++ g_debug ("same state as before, ignoring");
3768++ return;
3769++ }
3770++
3771++ /* save in local cache */
3772++ g_debug ("setting on_battery %i", on_battery);
3773++ refresh->priv->on_battery = on_battery;
3774++ if (!on_battery)
3775++ change_state (refresh);
3776++}
3777++
3778++static void
3779++get_properties_cb (GObject *object,
3780++ GAsyncResult *res,
3781++ GsdUpdatesRefresh *refresh)
3782++{
3783++ PkNetworkEnum state;
3784++ GError *error = NULL;
3785++ PkControl *control = PK_CONTROL(object);
3786++ gboolean ret;
3787++
3788++ /* get the result */
3789++ ret = pk_control_get_properties_finish (control, res, &error);
3790++ if (!ret) {
3791++ /* TRANSLATORS: backend is broken, and won't tell us what it supports */
3792++ g_warning ("could not get properties");
3793++ g_error_free (error);
3794++ goto out;
3795++ }
3796++
3797++ /* get values */
3798++ g_object_get (control,
3799++ "network-state", &state,
3800++ NULL);
3801++ refresh->priv->network_active = convert_network_state (refresh, state);
3802++out:
3803++ return;
3804++}
3805++
3806++static void
3807++session_presence_signal_cb (GDBusProxy *proxy,
3808++ gchar *sender_name,
3809++ gchar *signal_name,
3810++ GVariant *parameters,
3811++ GsdUpdatesRefresh *refresh)
3812++{
3813++ guint status;
3814++
3815++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (refresh));
3816++
3817++ if (g_strcmp0 (signal_name, "StatusChanged") != 0)
3818++ return;
3819++
3820++ /* map status code into boolean */
3821++ g_variant_get (parameters, "(u)", &status);
3822++ refresh->priv->session_idle = (status == PRESENCE_STATUS_IDLE);
3823++ g_debug ("setting is_idle %i",
3824++ refresh->priv->session_idle);
3825++ if (refresh->priv->session_idle)
3826++ change_state (refresh);
3827++
3828++}
3829++
3830++static void
3831++gsd_updates_refresh_init (GsdUpdatesRefresh *refresh)
3832++{
3833++ GVariant *status;
3834++ guint status_code;
3835++
3836++ refresh->priv = GSD_UPDATES_REFRESH_GET_PRIVATE (refresh);
3837++ refresh->priv->on_battery = FALSE;
3838++ refresh->priv->network_active = FALSE;
3839++ refresh->priv->timeout_id = 0;
3840++ refresh->priv->periodic_id = 0;
3841++
3842++ /* we need to know the updates frequency */
3843++ refresh->priv->settings = g_settings_new (GSD_SETTINGS_SCHEMA);
3844++ g_signal_connect (refresh->priv->settings, "changed",
3845++ G_CALLBACK (settings_key_changed_cb), refresh);
3846++
3847++ /* we need to query the last cache refresh time */
3848++ refresh->priv->control = pk_control_new ();
3849++ g_signal_connect (refresh->priv->control, "notify::network-state",
3850++ G_CALLBACK (notify_network_state_cb),
3851++ refresh);
3852++
3853++ /* get network state */
3854++ pk_control_get_properties_async (refresh->priv->control,
3855++ NULL,
3856++ (GAsyncReadyCallback) get_properties_cb,
3857++ refresh);
3858++
3859++ /* use a UpClient */
3860++ refresh->priv->client = up_client_new ();
3861++ g_signal_connect (refresh->priv->client, "notify::on-battery",
3862++ G_CALLBACK (gsd_updates_refresh_client_on_battery_cb), refresh);
3863++
3864++ /* get the battery state */
3865++ refresh->priv->on_battery = up_client_get_on_battery (refresh->priv->client);
3866++ g_debug ("setting on battery %i", refresh->priv->on_battery);
3867++
3868++ /* use gnome-session for the idle detection */
3869++ refresh->priv->proxy_session =
3870++ gnome_settings_bus_get_session_proxy ();
3871++ if (refresh->priv->proxy_session != NULL) {
3872++ g_signal_connect (G_DBUS_PROXY (refresh->priv->proxy_session),
3873++ "g-signal",
3874++ G_CALLBACK (session_presence_signal_cb),
3875++ refresh);
3876++ status = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (refresh->priv->proxy_session),
3877++ "status");
3878++ if (status) {
3879++ g_variant_get (status, "u", &status_code);
3880++ refresh->priv->session_idle = (status_code == PRESENCE_STATUS_IDLE);
3881++ g_variant_unref (status);
3882++ }
3883++ else {
3884++ refresh->priv->session_idle = FALSE;
3885++ }
3886++ }
3887++
3888++ /* we check this in case we miss one of the async signals */
3889++ refresh->priv->periodic_id =
3890++ g_timeout_add_seconds (PERIODIC_CHECK_TIME,
3891++ periodic_timeout_cb, refresh);
3892++ g_source_set_name_by_id (refresh->priv->periodic_id,
3893++ "[GsdUpdatesRefresh] periodic check");
3894++
3895++ /* check system state */
3896++ change_state (refresh);
3897++}
3898++
3899++static void
3900++gsd_updates_refresh_finalize (GObject *object)
3901++{
3902++ GsdUpdatesRefresh *refresh;
3903++
3904++ g_return_if_fail (GSD_IS_UPDATES_REFRESH (object));
3905++
3906++ refresh = GSD_UPDATES_REFRESH (object);
3907++ g_return_if_fail (refresh->priv != NULL);
3908++
3909++ if (refresh->priv->timeout_id != 0)
3910++ g_source_remove (refresh->priv->timeout_id);
3911++ if (refresh->priv->periodic_id != 0)
3912++ g_source_remove (refresh->priv->periodic_id);
3913++
3914++ g_signal_handlers_disconnect_by_data (refresh->priv->client, refresh);
3915++ g_signal_handlers_disconnect_by_data (refresh->priv->proxy_session, refresh);
3916++
3917++ g_object_unref (refresh->priv->control);
3918++ g_object_unref (refresh->priv->settings);
3919++ g_object_unref (refresh->priv->client);
3920++ if (refresh->priv->proxy_session != NULL)
3921++ g_object_unref (refresh->priv->proxy_session);
3922++
3923++ G_OBJECT_CLASS (gsd_updates_refresh_parent_class)->finalize (object);
3924++}
3925++
3926++GsdUpdatesRefresh *
3927++gsd_updates_refresh_new (void)
3928++{
3929++ GsdUpdatesRefresh *refresh;
3930++ refresh = g_object_new (GSD_TYPE_UPDATES_REFRESH, NULL);
3931++ return GSD_UPDATES_REFRESH (refresh);
3932++}
3933++
3934+Index: gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-refresh.h
3935+===================================================================
3936+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3937++++ gnome-settings-daemon-3.14.2/plugins/updates/gsd-updates-refresh.h 2014-12-02 00:06:35.441485533 +0100
3938+@@ -0,0 +1,52 @@
3939++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3940++ *
3941++ * Copyright (C) 2007-2011 Richard Hughes <richard@hughsie.com>
3942++ *
3943++ * Licensed under the GNU General Public License Version 2
3944++ *
3945++ * This program is free software; you can redistribute it and/or modify
3946++ * it under the terms of the GNU General Public License as published by
3947++ * the Free Software Foundation; either version 2 of the License, or
3948++ * (at your option) any later version.
3949++ *
3950++ * This program is distributed in the hope that it will be useful,
3951++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3952++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3953++ * GNU General Public License for more details.
3954++ *
3955++ * You should have received a copy of the GNU General Public License
3956++ * along with this program; if not, write to the Free Software
3957++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3958++ */
3959++
3960++#ifndef __GSD_UPDATES_REFRESH_H
3961++#define __GSD_UPDATES_REFRESH_H
3962++
3963++#include <glib-object.h>
3964++
3965++G_BEGIN_DECLS
3966++
3967++#define GSD_TYPE_UPDATES_REFRESH (gsd_updates_refresh_get_type ())
3968++#define GSD_UPDATES_REFRESH(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_UPDATES_REFRESH, GsdUpdatesRefresh))
3969++#define GSD_UPDATES_REFRESH_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_UPDATES_REFRESH, GsdUpdatesRefreshClass))
3970++#define GSD_IS_UPDATES_REFRESH(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_UPDATES_REFRESH))
3971++
3972++typedef struct GsdUpdatesRefreshPrivate GsdUpdatesRefreshPrivate;
3973++
3974++typedef struct
3975++{
3976++ GObject parent;
3977++ GsdUpdatesRefreshPrivate *priv;
3978++} GsdUpdatesRefresh;
3979++
3980++typedef struct
3981++{
3982++ GObjectClass parent_class;
3983++} GsdUpdatesRefreshClass;
3984++
3985++GType gsd_updates_refresh_get_type (void);
3986++GsdUpdatesRefresh *gsd_updates_refresh_new (void);
3987++
3988++G_END_DECLS
3989++
3990++#endif /* __GSD_UPDATES_REFRESH_H */
3991+Index: gnome-settings-daemon-3.14.2/plugins/updates/test-updates.c
3992+===================================================================
3993+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3994++++ gnome-settings-daemon-3.14.2/plugins/updates/test-updates.c 2014-12-02 00:06:35.441485533 +0100
3995+@@ -0,0 +1,7 @@
3996++#define NEW gsd_updates_manager_new
3997++#define START gsd_updates_manager_start
3998++#define STOP gsd_updates_manager_stop
3999++#define MANAGER GsdUpdatesManager
4000++#include "gsd-updates-manager.h"
4001++
4002++#include "test-plugin.h"
4003+Index: gnome-settings-daemon-3.14.2/plugins/updates/updates-design.svg
4004+===================================================================
4005+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4006++++ gnome-settings-daemon-3.14.2/plugins/updates/updates-design.svg 2014-12-02 00:06:35.441485533 +0100
4007+@@ -0,0 +1,765 @@
4008++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
4009++<!-- Created with Inkscape (http://www.inkscape.org/) -->
4010++
4011++<svg
4012++ xmlns:dc="http://purl.org/dc/elements/1.1/"
4013++ xmlns:cc="http://creativecommons.org/ns#"
4014++ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
4015++ xmlns:svg="http://www.w3.org/2000/svg"
4016++ xmlns="http://www.w3.org/2000/svg"
4017++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
4018++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
4019++ width="744.09448819"
4020++ height="1052.3622047"
4021++ id="svg2"
4022++ version="1.1"
4023++ inkscape:version="0.48.2 r9819"
4024++ sodipodi:docname="plan.svg"
4025++ inkscape:export-filename="/home/hughsie/Code/gnome3/gnome-settings-daemon/plugins/updates/docs/plan.png"
4026++ inkscape:export-xdpi="90.094635"
4027++ inkscape:export-ydpi="90.094635">
4028++ <defs
4029++ id="defs4">
4030++ <marker
4031++ inkscape:stockid="Arrow2Lend"
4032++ orient="auto"
4033++ refY="0.0"
4034++ refX="0.0"
4035++ id="Arrow2Lend"
4036++ style="overflow:visible;">
4037++ <path
4038++ id="path3789"
4039++ style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
4040++ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
4041++ transform="scale(1.1) rotate(180) translate(1,0)" />
4042++ </marker>
4043++ <marker
4044++ inkscape:stockid="Arrow1Mend"
4045++ orient="auto"
4046++ refY="0.0"
4047++ refX="0.0"
4048++ id="Arrow1Mend"
4049++ style="overflow:visible;">
4050++ <path
4051++ id="path3777"
4052++ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
4053++ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
4054++ transform="scale(0.4) rotate(180) translate(10,0)" />
4055++ </marker>
4056++ <marker
4057++ inkscape:stockid="Arrow2Lend"
4058++ orient="auto"
4059++ refY="0"
4060++ refX="0"
4061++ id="Arrow2Lend-7"
4062++ style="overflow:visible">
4063++ <path
4064++ inkscape:connector-curvature="0"
4065++ id="path3789-0"
4066++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4067++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4068++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4069++ </marker>
4070++ <marker
4071++ inkscape:stockid="Arrow2Lend"
4072++ orient="auto"
4073++ refY="0"
4074++ refX="0"
4075++ id="Arrow2Lend-0"
4076++ style="overflow:visible">
4077++ <path
4078++ inkscape:connector-curvature="0"
4079++ id="path3789-4"
4080++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4081++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4082++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4083++ </marker>
4084++ <marker
4085++ inkscape:stockid="Arrow2Lend"
4086++ orient="auto"
4087++ refY="0"
4088++ refX="0"
4089++ id="Arrow2Lend-2"
4090++ style="overflow:visible">
4091++ <path
4092++ inkscape:connector-curvature="0"
4093++ id="path3789-02"
4094++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4095++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4096++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4097++ </marker>
4098++ <marker
4099++ inkscape:stockid="Arrow2Lend"
4100++ orient="auto"
4101++ refY="0"
4102++ refX="0"
4103++ id="Arrow2Lend-4"
4104++ style="overflow:visible">
4105++ <path
4106++ inkscape:connector-curvature="0"
4107++ id="path3789-03"
4108++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4109++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4110++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4111++ </marker>
4112++ <marker
4113++ inkscape:stockid="Arrow2Lend"
4114++ orient="auto"
4115++ refY="0"
4116++ refX="0"
4117++ id="Arrow2Lend-6"
4118++ style="overflow:visible">
4119++ <path
4120++ inkscape:connector-curvature="0"
4121++ id="path3789-7"
4122++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4123++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4124++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4125++ </marker>
4126++ <marker
4127++ inkscape:stockid="Arrow2Lend"
4128++ orient="auto"
4129++ refY="0"
4130++ refX="0"
4131++ id="Arrow2Lend-48"
4132++ style="overflow:visible">
4133++ <path
4134++ inkscape:connector-curvature="0"
4135++ id="path3789-3"
4136++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4137++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4138++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4139++ </marker>
4140++ <marker
4141++ inkscape:stockid="Arrow2Lend"
4142++ orient="auto"
4143++ refY="0"
4144++ refX="0"
4145++ id="Arrow2Lend-8"
4146++ style="overflow:visible">
4147++ <path
4148++ inkscape:connector-curvature="0"
4149++ id="path3789-9"
4150++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4151++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4152++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4153++ </marker>
4154++ <marker
4155++ inkscape:stockid="Arrow2Lend"
4156++ orient="auto"
4157++ refY="0"
4158++ refX="0"
4159++ id="Arrow2Lend-5"
4160++ style="overflow:visible">
4161++ <path
4162++ inkscape:connector-curvature="0"
4163++ id="path3789-32"
4164++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4165++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4166++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4167++ </marker>
4168++ <marker
4169++ inkscape:stockid="Arrow2Lend"
4170++ orient="auto"
4171++ refY="0"
4172++ refX="0"
4173++ id="Arrow2Lend-54"
4174++ style="overflow:visible">
4175++ <path
4176++ inkscape:connector-curvature="0"
4177++ id="path3789-47"
4178++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4179++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4180++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4181++ </marker>
4182++ <marker
4183++ inkscape:stockid="Arrow2Lend"
4184++ orient="auto"
4185++ refY="0"
4186++ refX="0"
4187++ id="Arrow2Lend-60"
4188++ style="overflow:visible">
4189++ <path
4190++ inkscape:connector-curvature="0"
4191++ id="path3789-00"
4192++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4193++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4194++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4195++ </marker>
4196++ <marker
4197++ inkscape:stockid="Arrow2Lend"
4198++ orient="auto"
4199++ refY="0"
4200++ refX="0"
4201++ id="Arrow2Lend-9"
4202++ style="overflow:visible">
4203++ <path
4204++ inkscape:connector-curvature="0"
4205++ id="path3789-72"
4206++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4207++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4208++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4209++ </marker>
4210++ <marker
4211++ inkscape:stockid="Arrow2Lend"
4212++ orient="auto"
4213++ refY="0"
4214++ refX="0"
4215++ id="Arrow2Lend-09"
4216++ style="overflow:visible">
4217++ <path
4218++ inkscape:connector-curvature="0"
4219++ id="path3789-8"
4220++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4221++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4222++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4223++ </marker>
4224++ <marker
4225++ inkscape:stockid="Arrow2Lend"
4226++ orient="auto"
4227++ refY="0"
4228++ refX="0"
4229++ id="Arrow2Lend-45"
4230++ style="overflow:visible">
4231++ <path
4232++ inkscape:connector-curvature="0"
4233++ id="path3789-1"
4234++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4235++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4236++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4237++ </marker>
4238++ <marker
4239++ inkscape:stockid="Arrow2Lend"
4240++ orient="auto"
4241++ refY="0"
4242++ refX="0"
4243++ id="Arrow2Lend-98"
4244++ style="overflow:visible">
4245++ <path
4246++ inkscape:connector-curvature="0"
4247++ id="path3789-45"
4248++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4249++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4250++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4251++ </marker>
4252++ <marker
4253++ inkscape:stockid="Arrow2Lend"
4254++ orient="auto"
4255++ refY="0"
4256++ refX="0"
4257++ id="Arrow2Lend-50"
4258++ style="overflow:visible">
4259++ <path
4260++ inkscape:connector-curvature="0"
4261++ id="path3789-457"
4262++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4263++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4264++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4265++ </marker>
4266++ <marker
4267++ inkscape:stockid="Arrow2Lend"
4268++ orient="auto"
4269++ refY="0"
4270++ refX="0"
4271++ id="Arrow2Lend-63"
4272++ style="overflow:visible">
4273++ <path
4274++ inkscape:connector-curvature="0"
4275++ id="path3789-06"
4276++ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
4277++ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
4278++ transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
4279++ </marker>
4280++ </defs>
4281++ <sodipodi:namedview
4282++ id="base"
4283++ pagecolor="#ffffff"
4284++ bordercolor="#666666"
4285++ borderopacity="1.0"
4286++ inkscape:pageopacity="0.0"
4287++ inkscape:pageshadow="2"
4288++ inkscape:zoom="1.4"
4289++ inkscape:cx="370.94472"
4290++ inkscape:cy="350.46964"
4291++ inkscape:document-units="px"
4292++ inkscape:current-layer="layer1"
4293++ showgrid="true"
4294++ inkscape:window-width="1600"
4295++ inkscape:window-height="845"
4296++ inkscape:window-x="1920"
4297++ inkscape:window-y="542"
4298++ inkscape:window-maximized="1">
4299++ <inkscape:grid
4300++ type="xygrid"
4301++ id="grid2985"
4302++ empspacing="5"
4303++ visible="true"
4304++ enabled="true"
4305++ snapvisiblegridlinesonly="true" />
4306++ </sodipodi:namedview>
4307++ <metadata
4308++ id="metadata7">
4309++ <rdf:RDF>
4310++ <cc:Work
4311++ rdf:about="">
4312++ <dc:format>image/svg+xml</dc:format>
4313++ <dc:type
4314++ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
4315++ <dc:title></dc:title>
4316++ </cc:Work>
4317++ </rdf:RDF>
4318++ </metadata>
4319++ <g
4320++ inkscape:label="Layer 1"
4321++ inkscape:groupmode="layer"
4322++ id="layer1">
4323++ <rect
4324++ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.09627009;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4325++ id="rect5533"
4326++ width="550.0965"
4327++ height="930"
4328++ x="39.950954"
4329++ y="42.362183" />
4330++ <rect
4331++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.91287094;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4332++ id="rect2987"
4333++ width="180"
4334++ height="50"
4335++ x="110"
4336++ y="102.36217" />
4337++ <text
4338++ xml:space="preserve"
4339++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4340++ x="200"
4341++ y="122.36218"
4342++ id="text3757"
4343++ sodipodi:linespacing="125%"><tspan
4344++ sodipodi:role="line"
4345++ id="tspan3759"
4346++ x="200"
4347++ y="122.36218"
4348++ style="font-size:14px;text-align:center;text-anchor:middle">Wait for refresh due</tspan><tspan
4349++ sodipodi:role="line"
4350++ x="200"
4351++ y="139.86218"
4352++ id="tspan3761"
4353++ style="font-size:14px;text-align:center;text-anchor:middle">GetUpdates (typ. 1 day)</tspan></text>
4354++ <path
4355++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4356++ d="m 200,152.36217 0,30"
4357++ id="path3763"
4358++ inkscape:connector-curvature="0" />
4359++ <rect
4360++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.91287094;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4361++ id="rect2987-1"
4362++ width="180"
4363++ height="50"
4364++ x="110"
4365++ y="442.36218" />
4366++ <text
4367++ xml:space="preserve"
4368++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4369++ x="200"
4370++ y="470.36218"
4371++ id="text3757-1"
4372++ sodipodi:linespacing="125%"><tspan
4373++ sodipodi:role="line"
4374++ x="200"
4375++ y="470.36218"
4376++ id="tspan3761-5"
4377++ style="font-size:14px;text-align:center;text-anchor:middle">GetUpdates()</tspan></text>
4378++ <path
4379++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4380++ d="m 200,492.36217 0,30"
4381++ id="path3763-7"
4382++ inkscape:connector-curvature="0" />
4383++ <rect
4384++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.11863005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4385++ id="rect2987-4"
4386++ width="111.96233"
4387++ height="111.96233"
4388++ x="696.61267"
4389++ y="473.08511"
4390++ transform="matrix(0.89474433,0.44657876,-0.89474433,0.44657876,0,0)" />
4391++ <text
4392++ xml:space="preserve"
4393++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4394++ x="200"
4395++ y="568.36218"
4396++ id="text3757-12-7"
4397++ sodipodi:linespacing="125%"><tspan
4398++ sodipodi:role="line"
4399++ x="200"
4400++ y="568.36218"
4401++ id="tspan3761-8-2"
4402++ style="font-size:14px;text-align:center;text-anchor:middle">'Auto download'</tspan><tspan
4403++ sodipodi:role="line"
4404++ x="200"
4405++ y="585.86218"
4406++ style="font-size:14px;text-align:center;text-anchor:middle"
4407++ id="tspan4724">checkbox set?</tspan></text>
4408++ <text
4409++ xml:space="preserve"
4410++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4411++ x="200"
4412++ y="612.36218"
4413++ id="text3757-12-0-5"
4414++ sodipodi:linespacing="125%"><tspan
4415++ sodipodi:role="line"
4416++ x="200"
4417++ y="612.36218"
4418++ id="tspan3761-8-25-7"
4419++ style="font-size:14px;text-align:center;text-anchor:middle">Y</tspan></text>
4420++ <text
4421++ xml:space="preserve"
4422++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4423++ x="274"
4424++ y="576.36218"
4425++ id="text3757-12-0-8-7"
4426++ sodipodi:linespacing="125%"><tspan
4427++ sodipodi:role="line"
4428++ x="274"
4429++ y="576.36218"
4430++ id="tspan3761-8-25-8-3"
4431++ style="font-size:14px;text-align:center;text-anchor:middle">N</tspan></text>
4432++ <path
4433++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4434++ d="m 200,622.36217 0,30"
4435++ id="path3763-2-7"
4436++ inkscape:connector-curvature="0" />
4437++ <rect
4438++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.91287094;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4439++ id="rect2987-3"
4440++ width="180"
4441++ height="50"
4442++ x="110"
4443++ y="652.36218" />
4444++ <text
4445++ xml:space="preserve"
4446++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4447++ x="200"
4448++ y="672.36218"
4449++ id="text3757-2"
4450++ sodipodi:linespacing="125%"><tspan
4451++ sodipodi:role="line"
4452++ x="200"
4453++ y="672.36218"
4454++ id="tspan3761-7"
4455++ style="font-size:14px;text-align:center;text-anchor:middle">UpdatePackages</tspan><tspan
4456++ sodipodi:role="line"
4457++ x="200"
4458++ y="689.86218"
4459++ style="font-size:14px;text-align:center;text-anchor:middle"
4460++ id="tspan4862">(only-download)</tspan></text>
4461++ <path
4462++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4463++ d="m 200,702.36217 0,30"
4464++ id="path3763-1"
4465++ inkscape:connector-curvature="0" />
4466++ <rect
4467++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.11863005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4468++ id="rect2987-4-8"
4469++ width="111.96233"
4470++ height="111.96233"
4471++ x="931.73358"
4472++ y="708.20605"
4473++ transform="matrix(0.89474433,0.44657876,-0.89474433,0.44657876,0,0)" />
4474++ <text
4475++ xml:space="preserve"
4476++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4477++ x="200"
4478++ y="778.36218"
4479++ id="text3757-12-7-0"
4480++ sodipodi:linespacing="125%"><tspan
4481++ sodipodi:role="line"
4482++ x="200"
4483++ y="778.36218"
4484++ style="font-size:14px;text-align:center;text-anchor:middle"
4485++ id="tspan4724-3">Any security or</tspan><tspan
4486++ sodipodi:role="line"
4487++ x="200"
4488++ y="795.86218"
4489++ style="font-size:14px;text-align:center;text-anchor:middle"
4490++ id="tspan5002">critical updates?</tspan></text>
4491++ <text
4492++ xml:space="preserve"
4493++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4494++ x="200"
4495++ y="822.36218"
4496++ id="text3757-12-0-5-9"
4497++ sodipodi:linespacing="125%"><tspan
4498++ sodipodi:role="line"
4499++ x="200"
4500++ y="822.36218"
4501++ id="tspan3761-8-25-7-2"
4502++ style="font-size:14px;text-align:center;text-anchor:middle">Y</tspan></text>
4503++ <text
4504++ xml:space="preserve"
4505++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4506++ x="274"
4507++ y="786.36218"
4508++ id="text3757-12-0-8-7-2"
4509++ sodipodi:linespacing="125%"><tspan
4510++ sodipodi:role="line"
4511++ x="274"
4512++ y="786.36218"
4513++ id="tspan3761-8-25-8-3-2"
4514++ style="font-size:14px;text-align:center;text-anchor:middle">N</tspan></text>
4515++ <path
4516++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4517++ d="m 200,832.36216 0,30"
4518++ id="path3763-2-7-9"
4519++ inkscape:connector-curvature="0" />
4520++ <path
4521++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4522++ d="m 300,572.36217 20,0 0,140 -120,0"
4523++ id="path3763-2-4"
4524++ inkscape:connector-curvature="0"
4525++ sodipodi:nodetypes="cccc" />
4526++ <path
4527++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4528++ d="m 430,832.36217 0,30"
4529++ id="path3763-2-5"
4530++ inkscape:connector-curvature="0" />
4531++ <rect
4532++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.11863005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4533++ id="rect2987-4-9-5"
4534++ width="111.96233"
4535++ height="111.96233"
4536++ x="1060.2618"
4537++ y="579.67767"
4538++ transform="matrix(0.89474433,0.44657876,-0.89474433,0.44657876,0,0)" />
4539++ <text
4540++ xml:space="preserve"
4541++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4542++ x="430"
4543++ y="822.36218"
4544++ id="text3757-12-0-2"
4545++ sodipodi:linespacing="125%"><tspan
4546++ sodipodi:role="line"
4547++ x="430"
4548++ y="822.36218"
4549++ id="tspan3761-8-25-4"
4550++ style="font-size:14px;text-align:center;text-anchor:middle">Y</tspan></text>
4551++ <text
4552++ xml:space="preserve"
4553++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4554++ x="504"
4555++ y="786.36218"
4556++ id="text3757-12-0-8-8"
4557++ sodipodi:linespacing="125%"><tspan
4558++ sodipodi:role="line"
4559++ x="504"
4560++ y="786.36218"
4561++ id="tspan3761-8-25-8-34"
4562++ style="font-size:14px;text-align:center;text-anchor:middle">N</tspan></text>
4563++ <path
4564++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4565++ d="m 300,782.36217 30,0"
4566++ id="path3763-2-5-8"
4567++ inkscape:connector-curvature="0"
4568++ sodipodi:nodetypes="cc" />
4569++ <text
4570++ xml:space="preserve"
4571++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4572++ x="430"
4573++ y="778.36218"
4574++ id="text3757-12-7-0-7"
4575++ sodipodi:linespacing="125%"><tspan
4576++ sodipodi:role="line"
4577++ x="430"
4578++ y="778.36218"
4579++ style="font-size:14px;text-align:center;text-anchor:middle"
4580++ id="tspan5117">&gt; notify threshold?</tspan><tspan
4581++ sodipodi:role="line"
4582++ x="430"
4583++ y="795.86218"
4584++ style="font-size:14px;text-align:center;text-anchor:middle"
4585++ id="tspan5512">typ. 1 week</tspan></text>
4586++ <path
4587++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4588++ d="m 200,412.36218 0,30"
4589++ id="path3763-2-3"
4590++ inkscape:connector-curvature="0" />
4591++ <rect
4592++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.11863005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4593++ id="rect2987-4-9-50"
4594++ width="111.96233"
4595++ height="111.96233"
4596++ x="461.49176"
4597++ y="237.9642"
4598++ transform="matrix(0.89474433,0.44657876,-0.89474433,0.44657876,0,0)" />
4599++ <text
4600++ xml:space="preserve"
4601++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4602++ x="200"
4603++ y="402.36218"
4604++ id="text3757-12-0-4"
4605++ sodipodi:linespacing="125%"><tspan
4606++ sodipodi:role="line"
4607++ x="200"
4608++ y="402.36218"
4609++ id="tspan3761-8-25-6"
4610++ style="font-size:14px;text-align:center;text-anchor:middle">Y</tspan></text>
4611++ <text
4612++ xml:space="preserve"
4613++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4614++ x="274"
4615++ y="366.36218"
4616++ id="text3757-12-0-8-1"
4617++ sodipodi:linespacing="125%"><tspan
4618++ sodipodi:role="line"
4619++ x="274"
4620++ y="366.36218"
4621++ id="tspan3761-8-25-8-8"
4622++ style="font-size:14px;text-align:center;text-anchor:middle">N</tspan></text>
4623++ <text
4624++ xml:space="preserve"
4625++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4626++ x="200"
4627++ y="358.36218"
4628++ id="text3757-12-7-9-0"
4629++ sodipodi:linespacing="125%"><tspan
4630++ sodipodi:role="line"
4631++ x="200"
4632++ y="358.36218"
4633++ style="font-size:14px;text-align:center;text-anchor:middle"
4634++ id="tspan5187-6">'Use Mobile'</tspan><tspan
4635++ sodipodi:role="line"
4636++ x="200"
4637++ y="375.86218"
4638++ style="font-size:14px;text-align:center;text-anchor:middle"
4639++ id="tspan5360">checkbox set?</tspan></text>
4640++ <path
4641++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4642++ d="m 200,282.36217 0,29.99999"
4643++ id="path3763-2-70"
4644++ inkscape:connector-curvature="0" />
4645++ <rect
4646++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.11863005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4647++ id="rect2987-4-9-2"
4648++ width="111.96233"
4649++ height="111.96233"
4650++ x="315.9407"
4651++ y="92.413185"
4652++ transform="matrix(0.89474433,0.44657876,-0.89474433,0.44657876,0,0)" />
4653++ <text
4654++ xml:space="preserve"
4655++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4656++ x="200"
4657++ y="272.36218"
4658++ id="text3757-12-0-7"
4659++ sodipodi:linespacing="125%"><tspan
4660++ sodipodi:role="line"
4661++ x="200"
4662++ y="272.36218"
4663++ id="tspan3761-8-25-3"
4664++ style="font-size:14px;text-align:center;text-anchor:middle">Y</tspan></text>
4665++ <text
4666++ xml:space="preserve"
4667++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4668++ x="126"
4669++ y="236.36218"
4670++ id="text3757-12-0-8-0"
4671++ sodipodi:linespacing="125%"><tspan
4672++ sodipodi:role="line"
4673++ x="126"
4674++ y="236.36218"
4675++ id="tspan3761-8-25-8-7"
4676++ style="font-size:14px;text-align:center;text-anchor:middle">N</tspan></text>
4677++ <text
4678++ xml:space="preserve"
4679++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4680++ x="200"
4681++ y="228.36217"
4682++ id="text3757-12-7-9-9"
4683++ sodipodi:linespacing="125%"><tspan
4684++ sodipodi:role="line"
4685++ x="200"
4686++ y="228.36217"
4687++ style="font-size:14px;text-align:center;text-anchor:middle"
4688++ id="tspan5187-0">On GPRS or</tspan><tspan
4689++ sodipodi:role="line"
4690++ x="200"
4691++ y="245.86217"
4692++ style="font-size:14px;text-align:center;text-anchor:middle"
4693++ id="tspan5356">CDMA?</tspan></text>
4694++ <path
4695++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4696++ d="m 100,232.36218 -30,0 0,189.99999 130,0"
4697++ id="path3763-2-8"
4698++ inkscape:connector-curvature="0"
4699++ sodipodi:nodetypes="cccc" />
4700++ <path
4701++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4702++ d="m 200,912.36217 0,30 360,0 0,-869.999998 -360,0 0,29.999998"
4703++ id="path3763-2-54"
4704++ inkscape:connector-curvature="0"
4705++ sodipodi:nodetypes="cccccc" />
4706++ <path
4707++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4708++ d="m 300,362.36218 260,0"
4709++ id="path3763-2-70-1"
4710++ inkscape:connector-curvature="0"
4711++ sodipodi:nodetypes="cc" />
4712++ <rect
4713++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.91287094;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4714++ id="rect2987-3-6"
4715++ width="180"
4716++ height="50"
4717++ x="110"
4718++ y="862.36218" />
4719++ <text
4720++ xml:space="preserve"
4721++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4722++ x="200"
4723++ y="882.36218"
4724++ id="text3757-2-6"
4725++ sodipodi:linespacing="125%"><tspan
4726++ sodipodi:role="line"
4727++ x="200"
4728++ y="882.36218"
4729++ style="font-size:14px;text-align:center;text-anchor:middle"
4730++ id="tspan4862-3">Notify the user about</tspan><tspan
4731++ sodipodi:role="line"
4732++ x="200"
4733++ y="899.86218"
4734++ style="font-size:14px;text-align:center;text-anchor:middle"
4735++ id="tspan5472">important updates</tspan></text>
4736++ <path
4737++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4738++ d="m 530,782.36217 30,0"
4739++ id="path3763-1-6"
4740++ inkscape:connector-curvature="0"
4741++ sodipodi:nodetypes="cc" />
4742++ <rect
4743++ style="color:#000000;fill:#e9e9f1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.91287094;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
4744++ id="rect2987-3-6-0"
4745++ width="180"
4746++ height="50"
4747++ x="340"
4748++ y="862.36218" />
4749++ <text
4750++ xml:space="preserve"
4751++ style="font-size:10px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
4752++ x="430"
4753++ y="882.36218"
4754++ id="text3757-2-6-5"
4755++ sodipodi:linespacing="125%"><tspan
4756++ sodipodi:role="line"
4757++ x="430"
4758++ y="882.36218"
4759++ style="font-size:14px;text-align:center;text-anchor:middle"
4760++ id="tspan4862-3-5">Notify the user about</tspan><tspan
4761++ sodipodi:role="line"
4762++ x="430"
4763++ y="899.86218"
4764++ style="font-size:14px;text-align:center;text-anchor:middle"
4765++ id="tspan5472-3">regular updates</tspan></text>
4766++ <path
4767++ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow2Lend)"
4768++ d="m 430,912.36217 0,30"
4769++ id="path3763-1-6-0"
4770++ inkscape:connector-curvature="0" />
4771++ </g>
4772++</svg>
4773+Index: gnome-settings-daemon-3.14.2/plugins/updates/updates.gnome-settings-plugin.in
4774+===================================================================
4775+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
4776++++ gnome-settings-daemon-3.14.2/plugins/updates/updates.gnome-settings-plugin.in 2014-12-02 00:06:35.441485533 +0100
4777+@@ -0,0 +1,9 @@
4778++[GNOME Settings Plugin]
4779++Module=updates
4780++IAge=0
4781++Priority=300
4782++_Name=Updates
4783++_Description=Updates plugin
4784++Authors=Richard Hughes
4785++Copyright=Copyright © 2011
4786++Website=
4787+Index: gnome-settings-daemon-3.14.2/po/POTFILES.in
4788+===================================================================
4789+--- gnome-settings-daemon-3.14.2.orig/po/POTFILES.in 2014-12-02 00:06:35.445485473 +0100
4790++++ gnome-settings-daemon-3.14.2/po/POTFILES.in 2014-12-02 00:06:35.441485533 +0100
4791+@@ -13,6 +13,7 @@ data/org.gnome.settings-daemon.plugins.o
4792+ data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in
4793+ data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in.in
4794+ data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in.in
4795++data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in
4796+ data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in
4797+ data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in
4798+ gnome-settings-daemon/main.c
4799+@@ -54,6 +55,9 @@ plugins/smartcard/gsd-smartcard-manager.
4800+ plugins/smartcard/gsd-smartcard-service.c
4801+ [type: gettext/ini]plugins/smartcard/smartcard.gnome-settings-plugin.in
4802+ [type: gettext/ini]plugins/sound/sound.gnome-settings-plugin.in
4803++plugins/updates/gsd-updates-firmware.c
4804++plugins/updates/gsd-updates-manager.c
4805++[type: gettext/ini]plugins/updates/updates.gnome-settings-plugin.in
4806+ plugins/wacom/gsd-wacom-button-editor.c
4807+ plugins/wacom/gsd-wacom-device.c
4808+ plugins/wacom/gsd-wacom-key-shortcut-button.c
4809+Index: gnome-settings-daemon-3.14.2/po/POTFILES.skip
4810+===================================================================
4811+--- gnome-settings-daemon-3.14.2.orig/po/POTFILES.skip 2014-12-02 00:06:35.445485473 +0100
4812++++ gnome-settings-daemon-3.14.2/po/POTFILES.skip 2014-12-02 00:06:35.441485533 +0100
4813+@@ -19,6 +19,7 @@ data/org.gnome.settings-daemon.plugins.o
4814+ data/org.gnome.settings-daemon.plugins.power.gschema.xml.in
4815+ data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in
4816+ data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in
4817++data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in
4818+ data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in
4819+ data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in
4820+ plugins/automount/gnome-fallback-mount-helper.desktop.in
4821+Index: gnome-settings-daemon-3.14.2/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
4822+===================================================================
4823+--- gnome-settings-daemon-3.14.2.orig/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in 2014-12-02 00:06:35.445485473 +0100
4824++++ gnome-settings-daemon-3.14.2/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in 2014-12-02 00:06:35.441485533 +0100
4825+@@ -27,6 +27,7 @@
4826+ <child name="sharing" schema="org.gnome.settings-daemon.plugins.sharing"/>
4827+ <child name="smartcard" schema="org.gnome.settings-daemon.plugins.smartcard"/>
4828+ <child name="sound" schema="org.gnome.settings-daemon.plugins.sound"/>
4829++ <child name="updates" schema="org.gnome.settings-daemon.plugins.updates"/>
4830+ <child name="xrandr" schema="org.gnome.settings-daemon.plugins.xrandr"/>
4831+ <child name="xsettings" schema="org.gnome.settings-daemon.plugins.xsettings"/>
4832+ </schema>
4833
4834=== added file 'debian/patches/04_superP.patch'
4835--- debian/patches/04_superP.patch 1970-01-01 00:00:00 +0000
4836+++ debian/patches/04_superP.patch 2014-12-20 20:23:37 +0000
4837@@ -0,0 +1,33 @@
4838+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=623223
4839+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=651571
4840+Bug: https://bugzilla.gnome.org/show_bug.cgi?id=669423
4841+
4842+Index: gnome-settings-daemon-3.7.91/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in
4843+===================================================================
4844+--- gnome-settings-daemon-3.7.91.orig/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in 2013-03-08 14:33:20.000000000 +0000
4845++++ gnome-settings-daemon-3.7.91/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in 2013-03-08 14:33:20.000000000 +0000
4846+@@ -85,6 +85,11 @@
4847+ <_summary>Stop playback</_summary>
4848+ <_description>Binding to stop playback.</_description>
4849+ </key>
4850++ <key name="video-out" type="s">
4851++ <default>'&lt;Super&gt;p'</default>
4852++ <_summary>Video output</_summary>
4853++ <_description>Binding to switch the video output device.</_description>
4854++ </key>
4855+ <key name="volume-down" type="s">
4856+ <default>'XF86AudioLowerVolume'</default>
4857+ <_summary>Volume down</_summary>
4858+Index: gnome-settings-daemon-3.7.91/plugins/media-keys/shortcuts-list.h
4859+===================================================================
4860+--- gnome-settings-daemon-3.7.91.orig/plugins/media-keys/shortcuts-list.h 2013-03-08 14:33:20.000000000 +0000
4861++++ gnome-settings-daemon-3.7.91/plugins/media-keys/shortcuts-list.h 2013-03-08 14:34:41.000000000 +0000
4862+@@ -132,7 +132,7 @@
4863+ { FORWARD_KEY, NULL, N_("Forward"), "XF86AudioForward", SHELL_KEYBINDING_MODE_ALL },
4864+ { REPEAT_KEY, NULL, N_("Repeat"), "XF86AudioRepeat", SHELL_KEYBINDING_MODE_ALL },
4865+ { RANDOM_KEY, NULL, N_("Random Play"), "XF86AudioRandomPlay", SHELL_KEYBINDING_MODE_ALL },
4866+- { VIDEO_OUT_KEY, NULL, N_("Video Out"), "<Super>p", SHELL_KEYBINDING_MODE_ALL },
4867++ { VIDEO_OUT_KEY, "video-out", N_("Video Out"), NULL, SHELL_KEYBINDING_MODE_ALL },
4868+ /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */
4869+ { VIDEO_OUT_KEY, NULL, N_("Video Out"), "XF86Display", SHELL_KEYBINDING_MODE_ALL },
4870+ /* Key code of the XF86RotateWindows key (present on some tablets) */
4871
4872=== added file 'debian/patches/30_xrandr_dbus_init.patch'
4873--- debian/patches/30_xrandr_dbus_init.patch 1970-01-01 00:00:00 +0000
4874+++ debian/patches/30_xrandr_dbus_init.patch 2014-12-20 20:23:37 +0000
4875@@ -0,0 +1,65 @@
4876+From e4b1d27d5d1df77301a5c018ddfb086e4da9e8e4 Mon Sep 17 00:00:00 2001
4877+From: Rui Matos <tiagomatos@gmail.com>
4878+Date: Fri, 14 Nov 2014 23:27:54 +0100
4879+Subject: xrandr: Register our DBus API only after all other initialization
4880+
4881+Otherwise we risk being called and not have all out internal state
4882+ready (e.g. priv->rw_screen being NULL) leading to crashes.
4883+
4884+We also need to disown our well known name on stop() since we'll
4885+reaquire it if start() gets called again.
4886+
4887+https://bugzilla.gnome.org/show_bug.cgi?id=740151
4888+
4889+diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c
4890+index 007beab..67b3ed1 100644
4891+--- a/plugins/xrandr/gsd-xrandr-manager.c
4892++++ b/plugins/xrandr/gsd-xrandr-manager.c
4893+@@ -129,6 +129,7 @@ static void get_allowed_rotations_for_output (GnomeRRConfig *config,
4894+ GnomeRRRotation *out_rotations);
4895+ static void handle_fn_f7 (GsdXrandrManager *mgr, gint64 timestamp);
4896+ static void handle_rotate_windows (GsdXrandrManager *mgr, GnomeRRRotation rotation, gint64 timestamp);
4897++static void register_manager_dbus (GsdXrandrManager *manager);
4898+
4899+ G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT)
4900+
4901+@@ -1232,6 +1233,7 @@ on_rr_screen_acquired (GObject *object,
4902+ manager->priv->settings = g_settings_new (CONF_SCHEMA);
4903+
4904+ manager_init_devices (manager);
4905++ register_manager_dbus (manager);
4906+
4907+ log_close ();
4908+ }
4909+@@ -1283,6 +1285,9 @@ gsd_xrandr_manager_stop (GsdXrandrManager *manager)
4910+ manager->priv->upower_client = NULL;
4911+ }
4912+
4913++ if (manager->priv->name_id != 0)
4914++ g_bus_unown_name (manager->priv->name_id);
4915++
4916+ if (manager->priv->introspection_data) {
4917+ g_dbus_node_info_unref (manager->priv->introspection_data);
4918+ manager->priv->introspection_data = NULL;
4919+@@ -1341,9 +1346,6 @@ gsd_xrandr_manager_finalize (GObject *object)
4920+
4921+ gsd_xrandr_manager_stop (manager);
4922+
4923+- if (manager->priv->name_id != 0)
4924+- g_bus_unown_name (manager->priv->name_id);
4925+-
4926+ G_OBJECT_CLASS (gsd_xrandr_manager_parent_class)->finalize (object);
4927+ }
4928+
4929+@@ -1462,8 +1464,6 @@ gsd_xrandr_manager_new (void)
4930+ manager_object = g_object_new (GSD_TYPE_XRANDR_MANAGER, NULL);
4931+ g_object_add_weak_pointer (manager_object,
4932+ (gpointer *) &manager_object);
4933+-
4934+- register_manager_dbus (manager_object);
4935+ }
4936+
4937+ return GSD_XRANDR_MANAGER (manager_object);
4938+--
4939+cgit v0.10.1
4940+
4941
4942=== modified file 'debian/patches/43_disable_locale_settings.patch'
4943--- debian/patches/43_disable_locale_settings.patch 2014-09-23 23:33:37 +0000
4944+++ debian/patches/43_disable_locale_settings.patch 2014-12-20 20:23:37 +0000
4945@@ -9,17 +9,18 @@
4946 * settings by editing ~/.profile.
4947 *
4948
4949-Index: gnome-settings-daemon-3.12.2/gnome-settings-daemon/main.c
4950+Index: gnome-settings-daemon/gnome-settings-daemon/main.c
4951 ===================================================================
4952---- gnome-settings-daemon-3.12.2.orig/gnome-settings-daemon/main.c
4953-+++ gnome-settings-daemon-3.12.2/gnome-settings-daemon/main.c
4954-@@ -312,9 +312,6 @@ name_acquired_handler (GDBusConnection *
4955+--- gnome-settings-daemon.orig/gnome-settings-daemon/main.c
4956++++ gnome-settings-daemon/gnome-settings-daemon/main.c
4957+@@ -296,9 +296,7 @@ name_acquired_handler (GDBusConnection *
4958 GDBusProxy *proxy;
4959
4960 proxy = G_DBUS_PROXY (gnome_settings_bus_get_session_proxy ());
4961 - /* Always call this first, as Setenv can only be called before
4962 - any client registers */
4963 - set_locale (proxy);
4964- #ifdef HAVE_IBUS
4965++
4966 set_legacy_ibus_env_vars (proxy);
4967- #endif
4968+
4969+ start_settings_manager ();
4970
4971=== modified file 'debian/patches/53_sync_input_sources_to_accountsservice.patch'
4972--- debian/patches/53_sync_input_sources_to_accountsservice.patch 2014-09-23 23:33:37 +0000
4973+++ debian/patches/53_sync_input_sources_to_accountsservice.patch 2014-12-20 20:23:37 +0000
4974@@ -1,19 +1,24 @@
4975+---
4976+ configure.ac | 8 +++
4977+ plugins/keyboard/Makefile.am | 2
4978+ plugins/keyboard/gsd-keyboard-manager.c | 72 ++++++++++++++++++++++++++++++++
4979+ 3 files changed, 82 insertions(+)
4980+
4981 --- a/plugins/keyboard/gsd-keyboard-manager.c
4982 +++ b/plugins/keyboard/gsd-keyboard-manager.c
4983-@@ -47,6 +47,8 @@
4984- #include <ibus.h>
4985- #endif
4986+@@ -40,6 +40,8 @@
4987+ #include <X11/XKBlib.h>
4988+ #include <X11/keysym.h>
4989
4990 +#include <act/act.h>
4991 +
4992 #include "gnome-settings-bus.h"
4993 #include "gnome-settings-profile.h"
4994 #include "gsd-keyboard-manager.h"
4995-@@ -953,6 +955,67 @@
4996- g_free (rules_file_path);
4997+@@ -485,12 +487,75 @@ set_gtk_im_module (GSettings *settings,
4998 }
4999
5000-+static void
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: