Merge ~nteodosio/+git/ubuntu-pro:ubuntupro42.0 into ~nteodosio/+git/ubuntu-pro:ubuntu/42.0.1-1ubuntu2-debian-patches-applied
- Git
- lp:~nteodosio/+git/ubuntu-pro
- ubuntupro42.0
- Merge into ubuntu/42.0.1-1ubuntu2-deb...
Status: | Merged |
---|---|
Merge reported by: | Nathan Teodosio |
Merged at revision: | 61fdffb080766beac8c60d9c067cbd7861db509e |
Proposed branch: | ~nteodosio/+git/ubuntu-pro:ubuntupro42.0 |
Merge into: | ~nteodosio/+git/ubuntu-pro:ubuntu/42.0.1-1ubuntu2-debian-patches-applied |
Diff against target: |
3560 lines (+1673/-32) 22 files modified
data/meson.build (+0/-9) dev/null (+0/-12) gnome-initial-setup/gis-assistant.c (+8/-1) gnome-initial-setup/gis-page.c (+15/-0) gnome-initial-setup/gis-page.h (+2/-0) gnome-initial-setup/gnome-initial-setup.c (+3/-3) gnome-initial-setup/pages/meson.build (+1/-1) gnome-initial-setup/pages/ubuntu-pro/checkmark.svg (+1/-0) gnome-initial-setup/pages/ubuntu-pro/fail.svg (+1/-0) gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-attach-page.ui (+214/-0) gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-offer-page.ui (+165/-0) gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.c (+804/-0) gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.h (+110/-0) gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.ui (+39/-0) gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-services-page.ui (+124/-0) gnome-initial-setup/pages/ubuntu-pro/meson.build (+12/-0) gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro-dark.svg (+25/-0) gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro.svg (+1/-0) gnome-initial-setup/pages/ubuntu-pro/ubuntupro.gresource.xml (+14/-0) gnome-initial-setup/pages/ubuntu-pro/utils.c (+123/-0) gnome-initial-setup/pages/ubuntu-pro/utils.h (+7/-0) po/POTFILES.in (+4/-6) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher (community) | Approve | ||
Sergio Costas | Pending | ||
Robert Ancell | Pending | ||
Review via email: mp+434628@code.launchpad.net |
Commit message
Description of the change
This has 42.0.1-1ubuntu2 with all debian/patches applied as its base.
This has dependencies right for Jammy (tested in a virtual machine).
Have Polkit running if you don't: /usr/lib/
I use this script to test:
---->
#!/bin/sh
if ! [ -d build ]; then
mkdir build
meson build
fi
ninja -C build || exit 1
if [ "$1" = debug ]; then
XDG_
elif [ "$1" = harddebug ]; then
G_DEBUG=
else
XDG_
fi
<----
Nathan Teodosio (nteodosio) wrote (last edit ): | # |
Nathan Teodosio (nteodosio) wrote : | # |
> I'm very confused as to what this PR is doing - it's proposing merging two branches you control, not merging into the gnome-initial-setup branch that matches a released version. The information below also shows merge conflicts, so it seems broken.
This was my mistake, I targeted the wrong gnome-initial-setup version, now it's correctly rebased against Jammy's version 42.0.1-1ubuntu2.
- 5a0ed85... by Nathan Teodosio
-
UI: Remove unused ID and position properties.
- 5918804... by Nathan Teodosio
-
RestJSONResponse moved out of header file.
- a785fc4... by Nathan Teodosio
-
Use g_autofree/
g_autoptr. - 3d98ca2... by Nathan Teodosio
-
Remove unused values from Page1Private.
- 1626906... by Nathan Teodosio
-
contractToken -> contract_token.
- 7945f63... by Nathan Teodosio
-
Don't store pin in a variable, use it directly to update GTK label.
- 2311da4... by Nathan Teodosio
-
page{1,2,3} -> {offer,
attach, list_services}
Nathan Teodosio (nteodosio) wrote (last edit ): | # |
> There's no dispose methods for the page classes, so they leak data.
So those are sort of destructors, right? Are they supposed to look like this[1]? Documentation is a bit too laconic[2]. The print statements didn't trigger when I passed the pages nor when I killed the program. I suppose they would only be triggered at program termination, since GIS allows one to go back to a previous page?
[1]: https:/
[2]: https:/
- f405e6a... by Nathan Teodosio
-
Translatable strings in attach labels.
Nathan Teodosio (nteodosio) : | # |
- 6b60922... by Nathan Teodosio
-
Introduce back button, hijack back and next actions.
- 6859cf1... by Nathan Teodosio
-
Rename: list.?services-
>services - cf74e20... by Nathan Teodosio
-
Add some comments here and there.
- 65de5a9... by Nathan Teodosio
-
Introduce utils.[ch].
- 28b4b04... by Nathan Teodosio
-
Remove set_page_completion function.
- c8c8ddf... by Nathan Teodosio
-
Delegate page 1->2 transition to update_gui.
Avoids minor corner case whereby coming back to page 2
with an non-empty token field would have an unsensitive
Next button. - 5cd7136... by Nathan Teodosio
-
Use Ubuntu Pro API.
This way we don't have to hard code the contracts URL.
- 3c6d262... by Nathan Teodosio
-
Only attempt attachment after clicking "Next"
Including after receiving contract_token after submitting PIN.
- 3d4b6e8... by Nathan Teodosio
-
Increase margin between PIN and status icon.
- 96aea7b... by Nathan Teodosio
-
Add dark theme detector routine.
- cc5096e... by Nathan Teodosio
-
Use different Ubuntu SVG if dark theme in use.
While we are at it, remove display_checkmark function in favor of
the more generic map_scalable_image. - 8ba928a... by Nathan Teodosio
-
Add placeholder ubuntu-pro-dark.svg
Sebastien Bacher (seb128) wrote : | # |
Thanks. It's not a complete review just some notes as I got that version in the ubuntu-desktop ppa for testing
- the ubuntu-pro.svg is actually a png, we either need to convert it or rename, would be easier to handle as a svg
- we need to remove the livepatch page as well (it's currently being displayed in addition to the pro page when not using the --existing-user option)
- the services page doesn't have bullet point at the start of the lines for the services
and the current layout is better for review but we will need to include the changes in the ubuntu patch once we are ready
- 88a716b... by Nathan Teodosio
-
Add bullet points to services.
- 4329757... by Nathan Teodosio
-
Nuke livepatch.
Nathan Teodosio (nteodosio) wrote : | # |
- ubuntu-pro.svg was indeed a PNG at some point, but now it is should be a SVG. Perhaps you had an older version?
- done.
- done.
Sergio Costas (rastersoft-gmail) wrote : | # |
Added some comments.
- 4728536... by Nathan Teodosio
-
Make current_page an enum and use switches instead of ifs.
- 4b3d2d8... by Nathan Teodosio
-
g_print->g_warning for reporting unexpected status.
- adaf545... by Nathan Teodosio
-
Remove make_rest_req.
No longer needed after migrating to Pro API.
Nathan Teodosio (nteodosio) wrote : | # |
Thanks for the review Sergio!
- 5cc7993... by Nathan Teodosio
-
Implement dispose function and free tokens therein.
- 5fc5a92... by Nathan Teodosio
-
Disconnect network signal handler in destructor.
Sergio Costas (rastersoft-gmail) wrote : | # |
I think that now I did explain it better.
Sergio Costas (rastersoft-gmail) wrote : | # |
Ops... didn't see the last patch.
Sergio Costas (rastersoft-gmail) wrote : | # |
Added an extra comment about disposing the objects.
- 6777ad7... by Nathan Teodosio
-
Renaming only
- 0cd8cd6... by Nathan Teodosio
-
Free token upon successful attachment.
Sebastien Bacher (seb128) wrote : | # |
I've pushed the current version in the ppa and tested it, small notes
- indeed the svg icon is right now
- the magic token spinner is vertically aligned to the top of the pin, and same for the 'token valid' checkmark and label, could we align them with the middle instead?
- using the magic token workflow, after entering the token on the website and clicking 'next' it prompts for the password/spin for a while (expected) but then we need to click next again. Could we make it so it does the next action by itself at the end of the registration?
Nathan Teodosio (nteodosio) wrote (last edit ): | # |
> Could we make it so it does the next action by itself at the end of the registration?
That means go to the next page, correct? So we'd also want that for the
manual token? I.e.,
- [magic] type pin in browser > click next > prompt > (if success) go to
next page immediately
- [token] type token > Next(or Enter) > prompt > (if success) go to next page
immediately
Sebastien Bacher (seb128) wrote : | # |
yes, I was testing the magic workflow but the same principle is true for the manual token
- b324c7f... by Nathan Teodosio
-
Skip to the next page directly once attachment is complete...
If the user is in the attachment page.
- 48d183a... by Nathan Teodosio
-
Adjust margins of PIN
Nathan Teodosio (nteodosio) wrote : | # |
That is done. About
> the magic token spinner is vertically aligned to the top of the pin, and same for the 'token valid' checkmark and label, could we align them with the middle instead?
As discussed, it is centered for me in Yaru and Adwaita. Glade displays it centered too.
There was a slight difference between the PIN's top and bottom margin, which are now equal. I doubt that would account for it though...
Sebastien Bacher (seb128) wrote : | # |
It now moves to the next page as expected and it feels more centered in the VM with the margin change. Adding one typo in a comment to fix but functionally it works as expected. I'm going to do another review on the code later before doing the ack but I think it feels ready now
- e652065... by Nathan Teodosio
-
Typo
- b5e987e... by Nathan Teodosio
-
Update the list of files to translate.
Patch by Sebastien Bacher.
Sebastien Bacher (seb128) wrote : | # |
Great work Nathan, I think it's ready for upload! We need to retro-fit the changes into debian/patches now, probably as an update to 0001-Add-
Sergio Costas (rastersoft-gmail) wrote : | # |
Please, wait. I think that there are still some little changes that should be done, referred to the dispose.
Sebastien Bacher (seb128) wrote : | # |
Ack, we are not going to merge before next week at this point so we can go through another review round today and on Monday
- 3346f62... by Nathan Teodosio
-
UI: Padding
Robert Ancell (robert-ancell) wrote : | # |
The diff below shows some merge conflicts, i.e. '+<<<<<<< data/meson.build' - does this branch need updating?
Nathan Teodosio (nteodosio) wrote : | # |
Those are spurious, I don't know why Launchpad calculates them.
Am 2023/01/17 um 00:20 schrieb Robert Ancell:
> The diff below shows some merge conflicts, i.e. '+<<<<<<< data/meson.build' - does this branch need updating?
Sergio Costas (rastersoft-gmail) wrote : | # |
Sometimes git does odd things when doing a manual rebase... usually those odd things are fixed just by doing a "git rebase master" (or main, or the base branch from which you did the current branch).
- 04028f2... by Nathan Teodosio
-
Replace dummy by actual dark logo SVG.
Nathan Teodosio (nteodosio) wrote : | # |
Thanks Sergio, that did get rid of the conflicts.
- 007b430... by Nathan Teodosio
-
Indentation and margins for radio buttons.
- 61fdffb... by Nathan Teodosio
-
Remove leading spaces from radio buttons.
Robert Ancell (robert-ancell) wrote : | # |
Added some more comments inline.
Preview Diff
1 | diff --git a/data/com.ubuntu.welcome.policy.in b/data/com.ubuntu.welcome.policy.in |
2 | deleted file mode 100644 |
3 | index cf623d5..0000000 |
4 | --- a/data/com.ubuntu.welcome.policy.in |
5 | +++ /dev/null |
6 | @@ -1,21 +0,0 @@ |
7 | -<?xml version="1.0" encoding="UTF-8"?> |
8 | -<!DOCTYPE policyconfig PUBLIC |
9 | - "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" |
10 | - "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> |
11 | - |
12 | -<policyconfig> |
13 | - <vendor>Ubuntu Welcome</vendor> |
14 | - <vendor_url>https://www.ubuntu.com/</vendor_url> |
15 | - |
16 | - <action id="com.ubuntu.welcome.livepatch"> |
17 | - <description>Manage Livepatch</description> |
18 | - <message>Authentication is required to enable Livepatch</message> |
19 | - <defaults> |
20 | - <allow_any>no</allow_any> |
21 | - <allow_inactive>no</allow_inactive> |
22 | - <allow_active>auth_admin_keep</allow_active> |
23 | - </defaults> |
24 | - <annotate key="org.freedesktop.policykit.imply">io.snapcraft.snapd.login com.ubuntu.softwareproperties.applychanges </annotate> |
25 | - </action> |
26 | - |
27 | -</policyconfig> |
28 | \ No newline at end of file |
29 | diff --git a/data/meson.build b/data/meson.build |
30 | index 0fbb7d1..36c775a 100644 |
31 | --- a/data/meson.build |
32 | +++ b/data/meson.build |
33 | @@ -99,15 +99,6 @@ if enable_systemd |
34 | ) |
35 | endif |
36 | |
37 | -i18n.merge_file( |
38 | - input: 'com.ubuntu.welcome.policy.in', |
39 | - output: 'com.ubuntu.welcome.policy', |
40 | - install: true, |
41 | - install_dir: join_paths(data_dir, 'polkit-1', 'actions'), |
42 | - po_dir: po_dir, |
43 | - type: 'xml' |
44 | -) |
45 | - |
46 | rules_dir = join_paths(data_dir, 'polkit-1', 'rules.d') |
47 | configure_file( |
48 | input: '20-gnome-initial-setup.rules.in', |
49 | diff --git a/gnome-initial-setup/gis-assistant.c b/gnome-initial-setup/gis-assistant.c |
50 | index b71cd07..af6061f 100644 |
51 | --- a/gnome-initial-setup/gis-assistant.c |
52 | +++ b/gnome-initial-setup/gis-assistant.c |
53 | @@ -175,7 +175,8 @@ void |
54 | gis_assistant_previous_page (GisAssistant *assistant) |
55 | { |
56 | g_return_if_fail (assistant->current_page != NULL); |
57 | - switch_to (assistant, find_prev_page (assistant, assistant->current_page)); |
58 | + if (!gis_page_go_back(assistant->current_page)) |
59 | + switch_to (assistant, find_prev_page (assistant, assistant->current_page)); |
60 | } |
61 | |
62 | static void |
63 | @@ -260,6 +261,12 @@ update_applying_state (GisAssistant *assistant) |
64 | { |
65 | applying = gis_page_get_applying (assistant->current_page); |
66 | is_first_page = assistant->pages->data == assistant->current_page; |
67 | + /* Hack to prevent the next button from Ubuntu Pro attach page from |
68 | + * being sensitive when the page is first mapped. */ |
69 | + if (g_str_equal( |
70 | + GIS_PAGE_GET_CLASS(assistant->current_page)->page_id, "UbuntuPro" |
71 | + )) |
72 | + return; |
73 | } |
74 | gtk_widget_set_sensitive (assistant->forward, !applying); |
75 | gtk_widget_set_sensitive (assistant->done, !applying); |
76 | diff --git a/gnome-initial-setup/gis-page.c b/gnome-initial-setup/gis-page.c |
77 | index a6553c3..217b073 100644 |
78 | --- a/gnome-initial-setup/gis-page.c |
79 | +++ b/gnome-initial-setup/gis-page.c |
80 | @@ -202,6 +202,12 @@ gis_page_real_apply (GisPage *page, |
81 | return FALSE; |
82 | } |
83 | |
84 | +static gboolean |
85 | +gis_page_real_go_back (GisPage *page) |
86 | +{ |
87 | + return FALSE; |
88 | +} |
89 | + |
90 | static void |
91 | gis_page_class_init (GisPageClass *klass) |
92 | { |
93 | @@ -214,6 +220,7 @@ gis_page_class_init (GisPageClass *klass) |
94 | object_class->set_property = gis_page_set_property; |
95 | |
96 | klass->apply = gis_page_real_apply; |
97 | + klass->go_back = gis_page_real_go_back; |
98 | |
99 | obj_props[PROP_DRIVER] = |
100 | g_param_spec_object ("driver", "", "", GIS_TYPE_DRIVER, |
101 | @@ -386,6 +393,14 @@ gis_page_apply_begin (GisPage *page, |
102 | g_object_notify_by_pspec (G_OBJECT (page), obj_props[PROP_APPLYING]); |
103 | } |
104 | |
105 | +gboolean |
106 | +gis_page_go_back (GisPage *page) |
107 | +{ |
108 | + GisPageClass *klass; |
109 | + klass = GIS_PAGE_GET_CLASS (page); |
110 | + return klass->go_back(page); |
111 | +} |
112 | + |
113 | void |
114 | gis_page_apply_complete (GisPage *page, |
115 | gboolean valid) |
116 | diff --git a/gnome-initial-setup/gis-page.h b/gnome-initial-setup/gis-page.h |
117 | index 3d6b25d..03d1ccf 100644 |
118 | --- a/gnome-initial-setup/gis-page.h |
119 | +++ b/gnome-initial-setup/gis-page.h |
120 | @@ -57,6 +57,7 @@ struct _GisPageClass |
121 | void (*locale_changed) (GisPage *page); |
122 | gboolean (*apply) (GisPage *page, |
123 | GCancellable *cancellable); |
124 | + gboolean (*go_back) (GisPage *page); |
125 | gboolean (*save_data) (GisPage *page, |
126 | GError **error); |
127 | void (*shown) (GisPage *page); |
128 | @@ -81,6 +82,7 @@ void gis_page_locale_changed (GisPage *page); |
129 | void gis_page_apply_begin (GisPage *page, GisPageApplyCallback callback, gpointer user_data); |
130 | void gis_page_apply_cancel (GisPage *page); |
131 | void gis_page_apply_complete (GisPage *page, gboolean valid); |
132 | +gboolean gis_page_go_back (GisPage *page); |
133 | gboolean gis_page_get_applying (GisPage *page); |
134 | gboolean gis_page_save_data (GisPage *page, |
135 | GError **error); |
136 | diff --git a/gnome-initial-setup/gnome-initial-setup.c b/gnome-initial-setup/gnome-initial-setup.c |
137 | index 4fe6a55..00a2cfb 100644 |
138 | --- a/gnome-initial-setup/gnome-initial-setup.c |
139 | +++ b/gnome-initial-setup/gnome-initial-setup.c |
140 | @@ -46,7 +46,7 @@ |
141 | #include "pages/password/gis-password-page.h" |
142 | #include "pages/summary/gis-summary-page.h" |
143 | #include "pages/ubuntu-report/gis-ubuntu-report-page.h" |
144 | -#include "pages/livepatch/gis-livepatch-page.h" |
145 | +#include "pages/ubuntu-pro/gis-ubuntupro-page.h" |
146 | #include "pages/apps/gis-apps-page.h" |
147 | |
148 | #define VENDOR_PAGES_GROUP "pages" |
149 | @@ -89,7 +89,7 @@ static PageData page_table[] = { |
150 | |
151 | static PageData ubuntu_page_table[] = { |
152 | PAGE (goa, FALSE), |
153 | - PAGE (livepatch, FALSE), |
154 | + PAGE (ubuntu_pro, FALSE), |
155 | PAGE (ubuntu_report, FALSE), |
156 | PAGE (privacy, FALSE), |
157 | PAGE (account, TRUE), |
158 | @@ -99,8 +99,8 @@ static PageData ubuntu_page_table[] = { |
159 | }; |
160 | |
161 | static PageData unity_page_table[] = { |
162 | + PAGE (ubuntu_pro, FALSE), |
163 | PAGE (goa, FALSE), |
164 | - PAGE (livepatch, FALSE), |
165 | PAGE (ubuntu_report, FALSE), |
166 | PAGE (account, TRUE), |
167 | PAGE (password, TRUE), |
168 | diff --git a/gnome-initial-setup/pages/livepatch/gis-auth-dialog.c b/gnome-initial-setup/pages/livepatch/gis-auth-dialog.c |
169 | deleted file mode 100644 |
170 | index eceb26e..0000000 |
171 | --- a/gnome-initial-setup/pages/livepatch/gis-auth-dialog.c |
172 | +++ /dev/null |
173 | @@ -1,528 +0,0 @@ |
174 | -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ |
175 | -/* |
176 | - * Copyright (C) 2018 Canonical Ltd. |
177 | - * |
178 | - * This program is free software; you can redistribute it and/or |
179 | - * modify it under the terms of the GNU General Public License as |
180 | - * published by the Free Software Foundation; either version 2 of the |
181 | - * License, or (at your option) any later version. |
182 | - * |
183 | - * This program is distributed in the hope that it will be useful, but |
184 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
185 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
186 | - * General Public License for more details. |
187 | - * |
188 | - * You should have received a copy of the GNU General Public License |
189 | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
190 | - * |
191 | - * Written by: |
192 | - * Andrea Azzarone <andrea.azzarone@canonical.com> |
193 | - */ |
194 | - |
195 | -#include "gis-auth-dialog.h" |
196 | - |
197 | -#include <glib/gi18n.h> |
198 | -#define GOA_API_IS_SUBJECT_TO_CHANGE |
199 | -#include <goa/goa.h> |
200 | -#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE |
201 | -#include <goabackend/goabackend.h> |
202 | - |
203 | -struct _GisAuthDialog |
204 | -{ |
205 | - GtkDialog parent_instance; |
206 | - |
207 | - GoaClient *goa_client; |
208 | - GtkListStore *liststore_account; |
209 | - |
210 | - GtkWidget *error_bar; |
211 | - GtkWidget *label_error; |
212 | - GtkWidget *label_header; |
213 | - GtkWidget *combobox_account; |
214 | - GtkWidget *label_account; |
215 | - GtkWidget *button_add_another; |
216 | - GtkWidget *button_cancel; |
217 | - GtkWidget *button_continue; |
218 | - |
219 | - GCancellable *cancellable; |
220 | - guint error_timeout; |
221 | -}; |
222 | - |
223 | -static void gis_auth_dialog_initable_iface_init (GInitableIface *iface); |
224 | - |
225 | -G_DEFINE_TYPE_WITH_CODE (GisAuthDialog, gis_auth_dialog, GTK_TYPE_DIALOG, |
226 | - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gis_auth_dialog_initable_iface_init)) |
227 | - |
228 | -enum { |
229 | - COLUMN_ID, |
230 | - COLUMN_EMAIL, |
231 | - COLUMN_ACCOUNT, |
232 | - N_COLUMNS |
233 | -}; |
234 | - |
235 | -static gboolean |
236 | -gis_auth_dialog_ignore_account (GoaAccount *account) |
237 | -{ |
238 | - return g_strcmp0 (goa_account_get_provider_type (account), "ubuntusso") != 0; |
239 | -} |
240 | - |
241 | -static void gis_auth_dialog_set_error (GisAuthDialog *self, |
242 | - const gchar *text); |
243 | - |
244 | -static gboolean |
245 | -gis_auth_dialog_error_timeout_cb (GisAuthDialog *self) |
246 | -{ |
247 | - /* Hide the error bar */ |
248 | - gis_auth_dialog_set_error (self, NULL); |
249 | - return G_SOURCE_REMOVE; |
250 | -} |
251 | - |
252 | -static void |
253 | -gis_auth_dialog_set_error (GisAuthDialog *self, |
254 | - const gchar *text) |
255 | -{ |
256 | - /* Reset current error timeout */ |
257 | - if (self->error_timeout > 0) { |
258 | - g_source_remove (self->error_timeout); |
259 | - self->error_timeout = 0; |
260 | - } |
261 | - |
262 | - if (!text) { |
263 | - /* Hide the error bar if text is NULL */ |
264 | - gtk_info_bar_set_revealed (GTK_INFO_BAR (self->error_bar), FALSE); |
265 | - gtk_widget_set_visible (self->error_bar, FALSE); |
266 | - } else { |
267 | - /* Reveal the error bar if text is not NULL */ |
268 | - g_autofree gchar *markup = NULL; |
269 | - markup = g_strdup_printf (_("Failed to add an Ubuntu Single Sign-on account: %s."), text); |
270 | - gtk_label_set_markup (GTK_LABEL (self->label_error), markup); |
271 | - gtk_widget_set_visible (self->error_bar, TRUE); |
272 | - gtk_info_bar_set_revealed (GTK_INFO_BAR (self->error_bar), TRUE); |
273 | - self->error_timeout = g_timeout_add_seconds (10, (GSourceFunc) gis_auth_dialog_error_timeout_cb, self); |
274 | - } |
275 | -} |
276 | - |
277 | -static void |
278 | -gis_auth_dialog_set_header (GisAuthDialog *self, |
279 | - const gchar *text) |
280 | -{ |
281 | - g_autofree gchar *markup = NULL; |
282 | - markup = g_strdup_printf ("<span size='larger' weight='bold'>%s</span>", text); |
283 | - gtk_label_set_markup (GTK_LABEL (self->label_header), markup); |
284 | -} |
285 | - |
286 | -static gint |
287 | -gis_auth_dialog_get_naccounts (GisAuthDialog *self) |
288 | -{ |
289 | - return gtk_tree_model_iter_n_children (GTK_TREE_MODEL (self->liststore_account), NULL); |
290 | -} |
291 | - |
292 | -static gboolean |
293 | -gis_auth_dialog_get_nth_account_data (GisAuthDialog *self, |
294 | - gint n, |
295 | - ...) |
296 | -{ |
297 | - GtkTreeIter iter; |
298 | - va_list var_args; |
299 | - |
300 | - if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (self->liststore_account), &iter, NULL, n)) |
301 | - return FALSE; |
302 | - |
303 | - va_start (var_args, n); |
304 | - gtk_tree_model_get_valist (GTK_TREE_MODEL (self->liststore_account), &iter, var_args); |
305 | - va_end (var_args); |
306 | - |
307 | - return TRUE; |
308 | -} |
309 | - |
310 | -static void |
311 | -gis_auth_dialog_check_ui (GisAuthDialog *self, |
312 | - gboolean select) |
313 | -{ |
314 | - gint naccounts = gis_auth_dialog_get_naccounts (self); |
315 | - |
316 | - if (naccounts == 0) { |
317 | - gis_auth_dialog_set_header (self, _("To use Livepatch, you need to use an Ubuntu One Account.")); |
318 | - gtk_widget_set_visible (self->combobox_account, FALSE); |
319 | - gtk_widget_set_visible (self->label_account, FALSE); |
320 | - gtk_widget_set_visible (self->button_add_another, FALSE); |
321 | - gtk_button_set_label (GTK_BUTTON (self->button_continue), _("Sign In / Register…")); |
322 | - } else if (naccounts == 1) { |
323 | - g_autofree gchar *email = NULL; |
324 | - |
325 | - gis_auth_dialog_set_header (self, _("To use Livepatch, you need to use your Ubuntu One Account.")); |
326 | - gtk_widget_set_visible (self->combobox_account, FALSE); |
327 | - gtk_widget_set_visible (self->label_account, TRUE); |
328 | - gtk_widget_set_visible (self->button_add_another, TRUE); |
329 | - gtk_button_set_label (GTK_BUTTON (self->button_continue), _("Continue")); |
330 | - gis_auth_dialog_get_nth_account_data (self, 0, COLUMN_EMAIL, &email, -1); |
331 | - gtk_label_set_text (GTK_LABEL (self->label_account), email); |
332 | - } else { |
333 | - gis_auth_dialog_set_header (self, _("To use Livepatch, you need to use an Ubuntu One Account.")); |
334 | - gtk_widget_set_visible (self->combobox_account, TRUE); |
335 | - gtk_widget_set_visible (self->label_account, FALSE); |
336 | - gtk_widget_set_visible (self->button_add_another, TRUE); |
337 | - gtk_button_set_label (GTK_BUTTON (self->button_continue), _("Use")); |
338 | - |
339 | - if (select) { |
340 | - gtk_combo_box_set_active (GTK_COMBO_BOX (self->combobox_account), naccounts - 1); |
341 | - } else if (gtk_combo_box_get_active (GTK_COMBO_BOX (self->combobox_account)) == -1) { |
342 | - gtk_combo_box_set_active (GTK_COMBO_BOX (self->combobox_account), 0); |
343 | - } |
344 | - } |
345 | -} |
346 | - |
347 | -static gboolean |
348 | -gis_auth_dialog_get_account_iter (GisAuthDialog *self, |
349 | - GoaAccount *account, |
350 | - GtkTreeIter *iter) |
351 | -{ |
352 | - gboolean valid; |
353 | - |
354 | - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (self->liststore_account), iter, NULL, 0); |
355 | - |
356 | - while (valid) { |
357 | - g_autofree gchar *id; |
358 | - gtk_tree_model_get (GTK_TREE_MODEL (self->liststore_account), iter, COLUMN_ID, &id, -1); |
359 | - if (g_strcmp0 (id, goa_account_get_id (account)) == 0) |
360 | - return TRUE; |
361 | - else |
362 | - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (self->liststore_account), iter); |
363 | - } |
364 | - |
365 | - return FALSE; |
366 | -} |
367 | - |
368 | -static void |
369 | -gis_auth_dialog_add_account (GisAuthDialog *self, |
370 | - GoaAccount *account, |
371 | - gboolean select) |
372 | -{ |
373 | - GtkTreeIter iter; |
374 | - |
375 | - if (gis_auth_dialog_ignore_account (account) || |
376 | - gis_auth_dialog_get_account_iter (self, account, &iter)) |
377 | - return; |
378 | - |
379 | - gtk_list_store_append (self->liststore_account, &iter); |
380 | - gtk_list_store_set (self->liststore_account, &iter, |
381 | - COLUMN_ID, goa_account_get_id (account), |
382 | - COLUMN_EMAIL, goa_account_get_presentation_identity (account), |
383 | - COLUMN_ACCOUNT, account, |
384 | - -1); |
385 | - |
386 | - gis_auth_dialog_check_ui (self, select); |
387 | -} |
388 | - |
389 | -static void |
390 | -gis_auth_dialog_remove_account (GisAuthDialog *self, |
391 | - GoaAccount *account) |
392 | -{ |
393 | - GtkTreeIter iter; |
394 | - |
395 | - if (gis_auth_dialog_ignore_account (account) || |
396 | - !gis_auth_dialog_get_account_iter (self, account, &iter)) |
397 | - return; |
398 | - |
399 | - gtk_list_store_remove (self->liststore_account, &iter); |
400 | - gis_auth_dialog_check_ui (self, FALSE); |
401 | -} |
402 | - |
403 | -static void |
404 | -gis_auth_dialog_setup_model (GisAuthDialog *self) |
405 | -{ |
406 | - g_autoptr(GList) accounts = goa_client_get_accounts (self->goa_client); |
407 | - |
408 | - for (GList *l = accounts; l != NULL; l = l->next) { |
409 | - gis_auth_dialog_add_account (self, goa_object_peek_account (l->data), FALSE); |
410 | - g_object_unref (l->data); |
411 | - } |
412 | -} |
413 | - |
414 | -static GoaAccount* |
415 | -gis_auth_dialog_show_sso (GisAuthDialog *self, |
416 | - GoaAccount *account) |
417 | -{ |
418 | - g_autoptr(GoaProvider) provider = NULL; |
419 | - g_autoptr(GError) error = NULL; |
420 | - GoaObject *goa_object = NULL; |
421 | - GoaAccount *ret = NULL; |
422 | - |
423 | - /* Check if ubuntusso accounts are supported */ |
424 | - provider = goa_provider_get_for_provider_type ("ubuntusso"); |
425 | - if (provider == NULL) { |
426 | - gis_auth_dialog_set_error (self, _("Ubuntu Single Sign-on accounts are not supported")); |
427 | - goto out; |
428 | - } |
429 | - |
430 | - if (!account) { |
431 | - GtkWidget *dialog = NULL; |
432 | - /* Show the login dialog */ |
433 | - dialog = gtk_dialog_new_with_buttons (_("Add Account"), |
434 | - GTK_WINDOW (self), |
435 | - GTK_DIALOG_MODAL |
436 | - | GTK_DIALOG_DESTROY_WITH_PARENT |
437 | - | GTK_DIALOG_USE_HEADER_BAR, |
438 | - NULL, NULL); |
439 | - |
440 | - /* Set dialog to not resize. */ |
441 | - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); |
442 | - |
443 | - goa_object = goa_provider_add_account (provider, |
444 | - self->goa_client, |
445 | - GTK_DIALOG (dialog), |
446 | - GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), |
447 | - &error); |
448 | - |
449 | - gtk_widget_destroy (dialog); |
450 | - } else { |
451 | - /* Show the refresh dialog */ |
452 | - goa_object = goa_client_lookup_by_id (self->goa_client, goa_account_get_id (account)); |
453 | - goa_provider_refresh_account (provider, |
454 | - self->goa_client, |
455 | - goa_object, |
456 | - GTK_WINDOW (self), |
457 | - &error); |
458 | - } |
459 | - |
460 | - if (error) { |
461 | - if (!g_error_matches (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED)) |
462 | - gis_auth_dialog_set_error (self, error->message); |
463 | - goto out; |
464 | - } |
465 | - |
466 | - ret = goa_object_get_account (goa_object); |
467 | - |
468 | - out: |
469 | - g_clear_object (&goa_object); |
470 | - return ret; |
471 | -} |
472 | - |
473 | -static GoaAccount* |
474 | -gis_auth_dialog_get_selected_account (GisAuthDialog *self) |
475 | -{ |
476 | - GoaAccount *goa_account = NULL; |
477 | - gint naccounts = gis_auth_dialog_get_naccounts (self); |
478 | - |
479 | - if (naccounts == 1) { |
480 | - gis_auth_dialog_get_nth_account_data (self, 0, COLUMN_ACCOUNT, &goa_account, -1); |
481 | - } else if (naccounts > 1) { |
482 | - gint active = gtk_combo_box_get_active (GTK_COMBO_BOX (self->combobox_account)); |
483 | - gis_auth_dialog_get_nth_account_data (self, active, COLUMN_ACCOUNT, &goa_account, -1); |
484 | - } |
485 | - |
486 | - return goa_account; |
487 | -} |
488 | - |
489 | -void |
490 | -gis_auth_dialog_ensure_crendentials_cb (GObject *source_object, |
491 | - GAsyncResult *res, |
492 | - gpointer user_data) |
493 | -{ |
494 | - GisAuthDialog *self = (GisAuthDialog*) user_data; |
495 | - GoaAccount *account = GOA_ACCOUNT (source_object); |
496 | - g_autoptr(GError) error = NULL; |
497 | - |
498 | - if (!goa_account_call_ensure_credentials_finish (account, NULL, res, &error)) { |
499 | - if (g_error_matches (error, GOA_ERROR, GOA_ERROR_NOT_AUTHORIZED)) { |
500 | - /* Show the refresh account is credentials are expired */ |
501 | - account = gis_auth_dialog_show_sso (self, account); |
502 | - /* account is NULL in case of error or dismissal */ |
503 | - if (account != NULL) { |
504 | - gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK); |
505 | - g_object_unref (account); |
506 | - } |
507 | - } |
508 | - } else { |
509 | - gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK); |
510 | - } |
511 | -} |
512 | - |
513 | -static void |
514 | -gis_auth_dialog_response_if_valid (GisAuthDialog *self) |
515 | -{ |
516 | - GoaAccount *goa_account = gis_auth_dialog_get_selected_account (self); |
517 | - |
518 | - if (goa_account) |
519 | - goa_account_call_ensure_credentials (goa_account, |
520 | - self->cancellable, |
521 | - gis_auth_dialog_ensure_crendentials_cb, |
522 | - self); |
523 | - |
524 | - g_clear_object (&goa_account); |
525 | -} |
526 | - |
527 | -static void |
528 | -gis_auth_dialog_account_added_cb (GoaClient *client, |
529 | - GoaObject *object, |
530 | - GisAuthDialog *self) |
531 | -{ |
532 | - GoaAccount *account = goa_object_peek_account (object); |
533 | - gis_auth_dialog_add_account (self, account, FALSE); |
534 | -} |
535 | - |
536 | -static void |
537 | -gis_auth_dialog_account_removed_cb (GoaClient *client, |
538 | - GoaObject *object, |
539 | - GisAuthDialog *self) |
540 | -{ |
541 | - GoaAccount *account = goa_object_peek_account (object); |
542 | - gis_auth_dialog_remove_account (self, account); |
543 | -} |
544 | - |
545 | -static void |
546 | -gis_auth_dialog_button_add_another_cb (GtkButton *button, |
547 | - GisAuthDialog *self) |
548 | -{ |
549 | - GoaAccount *account; |
550 | - |
551 | - g_signal_handlers_block_by_func (self->goa_client, gis_auth_dialog_account_added_cb, self); |
552 | - |
553 | - account = gis_auth_dialog_show_sso (self, NULL); |
554 | - |
555 | - /* account is NULL in case of error or dismissal */ |
556 | - if (account != NULL) { |
557 | - gis_auth_dialog_add_account (self, account, TRUE); |
558 | - gis_auth_dialog_response_if_valid (self); |
559 | - g_object_unref (account); |
560 | - } |
561 | - |
562 | - g_signal_handlers_unblock_by_func (self->goa_client, gis_auth_dialog_account_added_cb, self); |
563 | -} |
564 | - |
565 | -static void |
566 | -gis_auth_dialog_button_cancel_cb (GtkButton *button, |
567 | - GisAuthDialog *self) |
568 | -{ |
569 | - gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_CANCEL); |
570 | -} |
571 | - |
572 | -static void |
573 | -gis_auth_dialog_button_continue_cb (GtkButton *button, |
574 | - GisAuthDialog *self) |
575 | -{ |
576 | - gint naccounts = gis_auth_dialog_get_naccounts (self); |
577 | - |
578 | - if (naccounts == 0) |
579 | - gis_auth_dialog_button_add_another_cb (GTK_BUTTON (self->button_add_another), self); |
580 | - else |
581 | - gis_auth_dialog_response_if_valid (self); |
582 | -} |
583 | - |
584 | -/* GObject */ |
585 | - |
586 | -static void |
587 | -gis_auth_dialog_dispose (GObject *object) |
588 | -{ |
589 | - GisAuthDialog *self = GIS_AUTH_DIALOG (object); |
590 | - |
591 | - g_clear_object (&self->goa_client); |
592 | - |
593 | - if (self->error_timeout > 0) { |
594 | - g_source_remove (self->error_timeout); |
595 | - self->error_timeout = 0; |
596 | - } |
597 | - |
598 | - g_cancellable_cancel (self->cancellable); |
599 | - g_clear_object (&self->cancellable); |
600 | - |
601 | - G_OBJECT_CLASS (gis_auth_dialog_parent_class)->dispose (object); |
602 | -} |
603 | - |
604 | -static void |
605 | -gis_auth_dialog_class_init (GisAuthDialogClass *klass) |
606 | -{ |
607 | - GObjectClass *object_class = G_OBJECT_CLASS (klass); |
608 | - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); |
609 | - |
610 | - object_class->dispose = gis_auth_dialog_dispose; |
611 | - |
612 | - gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/initial-setup/gis-auth-dialog.ui"); |
613 | - |
614 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, error_bar); |
615 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, label_error); |
616 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, label_header); |
617 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, combobox_account); |
618 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, label_account); |
619 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, button_add_another); |
620 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, button_cancel); |
621 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, button_continue); |
622 | - gtk_widget_class_bind_template_child (widget_class, GisAuthDialog, liststore_account); |
623 | - |
624 | - |
625 | - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), gis_auth_dialog_button_add_another_cb); |
626 | - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), gis_auth_dialog_button_cancel_cb); |
627 | - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), gis_auth_dialog_button_continue_cb); |
628 | -} |
629 | - |
630 | -static void |
631 | -gis_auth_dialog_init (GisAuthDialog *self) |
632 | -{ |
633 | - self->cancellable = g_cancellable_new (); |
634 | - |
635 | - gtk_widget_init_template (GTK_WIDGET (self)); |
636 | - gtk_widget_grab_focus (self->button_continue); |
637 | -} |
638 | - |
639 | -/* GInitable */ |
640 | - |
641 | -static gboolean |
642 | -gis_auth_dialog_initable_init (GInitable *initable, |
643 | - GCancellable *cancellable, |
644 | - GError **error) |
645 | -{ |
646 | - GisAuthDialog *self; |
647 | - |
648 | - g_return_val_if_fail (GIS_IS_AUTH_DIALOG (initable), FALSE); |
649 | - |
650 | - self = GIS_AUTH_DIALOG (initable); |
651 | - |
652 | - self->goa_client = goa_client_new_sync (NULL, error); |
653 | - if (!self->goa_client) |
654 | - return FALSE; |
655 | - |
656 | - gis_auth_dialog_setup_model (self); |
657 | - gis_auth_dialog_check_ui (self, FALSE); |
658 | - |
659 | - /* Be ready to other accounts */ |
660 | - g_signal_connect (self->goa_client, "account-added", G_CALLBACK (gis_auth_dialog_account_added_cb), self); |
661 | - g_signal_connect (self->goa_client, "account-removed", G_CALLBACK (gis_auth_dialog_account_removed_cb), self); |
662 | - |
663 | - return TRUE; |
664 | -} |
665 | - |
666 | -static void |
667 | -gis_auth_dialog_initable_iface_init (GInitableIface *iface) |
668 | -{ |
669 | - iface->init = gis_auth_dialog_initable_init; |
670 | -} |
671 | - |
672 | -/* Public API */ |
673 | - |
674 | -GtkWidget * |
675 | -gis_auth_dialog_new (GError **error) |
676 | -{ |
677 | - GisAuthDialog *dialog; |
678 | - |
679 | - dialog = g_initable_new (GIS_TYPE_AUTH_DIALOG, |
680 | - NULL, error, |
681 | - "title", "", |
682 | - NULL); |
683 | - |
684 | - return GTK_WIDGET (dialog); |
685 | -} |
686 | - |
687 | -gchar * |
688 | -gis_auth_dialog_get_account_id (GisAuthDialog *self) |
689 | -{ |
690 | - GoaAccount *goa_account; |
691 | - gchar *account_id = NULL; |
692 | - |
693 | - g_return_val_if_fail (GIS_IS_AUTH_DIALOG (self), NULL); |
694 | - |
695 | - goa_account = gis_auth_dialog_get_selected_account (self); |
696 | - if (goa_account) |
697 | - account_id = goa_account_dup_id (goa_account); |
698 | - |
699 | - g_clear_object (&goa_account); |
700 | - return account_id; |
701 | -} |
702 | diff --git a/gnome-initial-setup/pages/livepatch/gis-auth-dialog.h b/gnome-initial-setup/pages/livepatch/gis-auth-dialog.h |
703 | deleted file mode 100644 |
704 | index 09bfb69..0000000 |
705 | --- a/gnome-initial-setup/pages/livepatch/gis-auth-dialog.h |
706 | +++ /dev/null |
707 | @@ -1,40 +0,0 @@ |
708 | -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ |
709 | -/* |
710 | - * Copyright (C) 2018 Canonical Ltd. |
711 | - * |
712 | - * This program is free software; you can redistribute it and/or |
713 | - * modify it under the terms of the GNU General Public License as |
714 | - * published by the Free Software Foundation; either version 2 of the |
715 | - * License, or (at your option) any later version. |
716 | - * |
717 | - * This program is distributed in the hope that it will be useful, but |
718 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
719 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
720 | - * General Public License for more details. |
721 | - * |
722 | - * You should have received a copy of the GNU General Public License |
723 | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
724 | - * |
725 | - * Written by: |
726 | - * Andrea Azzarone <andrea.azzarone@canonical.com> |
727 | - */ |
728 | - |
729 | -#ifndef __GIS_AUTH_DIALOG_H__ |
730 | -#define __GIS_AUTH_DIALOG_H__ |
731 | - |
732 | -#define GOA_API_IS_SUBJECT_TO_CHANGE |
733 | -#include <goa/goa.h> |
734 | -#include <gtk/gtk.h> |
735 | - |
736 | -G_BEGIN_DECLS |
737 | - |
738 | -#define GIS_TYPE_AUTH_DIALOG (gis_auth_dialog_get_type ()) |
739 | - |
740 | -G_DECLARE_FINAL_TYPE (GisAuthDialog, gis_auth_dialog, GIS, AUTH_DIALOG, GtkDialog) |
741 | - |
742 | -GtkWidget *gis_auth_dialog_new (); |
743 | -gchar *gis_auth_dialog_get_account_id (GisAuthDialog *dialog); |
744 | - |
745 | -G_END_DECLS |
746 | - |
747 | -#endif /* __GIS_AUTH_DIALOG_H__ */ |
748 | diff --git a/gnome-initial-setup/pages/livepatch/gis-auth-dialog.ui b/gnome-initial-setup/pages/livepatch/gis-auth-dialog.ui |
749 | deleted file mode 100644 |
750 | index 0fe40b2..0000000 |
751 | --- a/gnome-initial-setup/pages/livepatch/gis-auth-dialog.ui |
752 | +++ /dev/null |
753 | @@ -1,231 +0,0 @@ |
754 | -<?xml version="1.0" encoding="UTF-8"?> |
755 | -<!-- Generated with glade 3.22.1 --> |
756 | -<interface> |
757 | - <requires lib="gtk+" version="3.10"/> |
758 | - <object class="GtkListStore" id="liststore_account"> |
759 | - <columns> |
760 | - <!-- column-name Id --> |
761 | - <column type="gchararray"/> |
762 | - <!-- column-name Email --> |
763 | - <column type="gchararray"/> |
764 | - <!-- column-name Account --> |
765 | - <column type="GObject"/> |
766 | - </columns> |
767 | - </object> |
768 | - <template class="GisAuthDialog" parent="GtkDialog"> |
769 | - <property name="can_focus">False</property> |
770 | - <property name="resizable">False</property> |
771 | - <property name="type_hint">dialog</property> |
772 | - <child> |
773 | - <placeholder/> |
774 | - </child> |
775 | - <child internal-child="vbox"> |
776 | - <object class="GtkBox"> |
777 | - <property name="can_focus">False</property> |
778 | - <property name="orientation">vertical</property> |
779 | - <property name="spacing">2</property> |
780 | - <child internal-child="action_area"> |
781 | - <object class="GtkButtonBox"> |
782 | - <property name="can_focus">False</property> |
783 | - <child> |
784 | - <object class="GtkButton" id="button_add_another"> |
785 | - <property name="label" translatable="yes">Add another…</property> |
786 | - <property name="visible">True</property> |
787 | - <property name="can_focus">True</property> |
788 | - <property name="receives_default">True</property> |
789 | - <signal name="clicked" handler="gis_auth_dialog_button_add_another_cb" swapped="no"/> |
790 | - </object> |
791 | - <packing> |
792 | - <property name="expand">True</property> |
793 | - <property name="fill">True</property> |
794 | - <property name="position">0</property> |
795 | - <property name="secondary">True</property> |
796 | - <property name="non_homogeneous">True</property> |
797 | - </packing> |
798 | - </child> |
799 | - <child> |
800 | - <object class="GtkButton" id="button_cancel"> |
801 | - <property name="label" translatable="yes">Cancel</property> |
802 | - <property name="visible">True</property> |
803 | - <property name="can_focus">True</property> |
804 | - <property name="receives_default">True</property> |
805 | - <signal name="clicked" handler="gis_auth_dialog_button_cancel_cb" swapped="no"/> |
806 | - </object> |
807 | - <packing> |
808 | - <property name="expand">True</property> |
809 | - <property name="fill">True</property> |
810 | - <property name="position">2</property> |
811 | - <property name="non_homogeneous">True</property> |
812 | - </packing> |
813 | - </child> |
814 | - <child> |
815 | - <object class="GtkButton" id="button_continue"> |
816 | - <property name="visible">True</property> |
817 | - <property name="can_focus">True</property> |
818 | - <property name="receives_default">True</property> |
819 | - <signal name="clicked" handler="gis_auth_dialog_button_continue_cb" swapped="no"/> |
820 | - </object> |
821 | - <packing> |
822 | - <property name="expand">True</property> |
823 | - <property name="fill">True</property> |
824 | - <property name="position">3</property> |
825 | - <property name="non_homogeneous">True</property> |
826 | - </packing> |
827 | - </child> |
828 | - </object> |
829 | - <packing> |
830 | - <property name="expand">True</property> |
831 | - <property name="fill">True</property> |
832 | - <property name="position">0</property> |
833 | - </packing> |
834 | - </child> |
835 | - <child> |
836 | - <object class="GtkInfoBar" id="error_bar"> |
837 | - <property name="can_focus">False</property> |
838 | - <property name="no_show_all">True</property> |
839 | - <property name="message_type">error</property> |
840 | - <property name="revealed">False</property> |
841 | - <child internal-child="action_area"> |
842 | - <object class="GtkButtonBox"> |
843 | - <property name="visible">True</property> |
844 | - <property name="can_focus">False</property> |
845 | - <property name="spacing">6</property> |
846 | - <property name="layout_style">end</property> |
847 | - <child> |
848 | - <placeholder/> |
849 | - </child> |
850 | - </object> |
851 | - <packing> |
852 | - <property name="expand">True</property> |
853 | - <property name="fill">True</property> |
854 | - <property name="position">0</property> |
855 | - </packing> |
856 | - </child> |
857 | - <child internal-child="content_area"> |
858 | - <object class="GtkBox"> |
859 | - <property name="visible">True</property> |
860 | - <property name="can_focus">False</property> |
861 | - <property name="spacing">16</property> |
862 | - <child> |
863 | - <object class="GtkLabel" id="label_error"> |
864 | - <property name="visible">True</property> |
865 | - <property name="can_focus">False</property> |
866 | - <property name="justify">fill</property> |
867 | - <property name="wrap">True</property> |
868 | - <property name="width_chars">0</property> |
869 | - <property name="max_width_chars">50</property> |
870 | - </object> |
871 | - <packing> |
872 | - <property name="expand">False</property> |
873 | - <property name="fill">True</property> |
874 | - <property name="position">0</property> |
875 | - </packing> |
876 | - </child> |
877 | - </object> |
878 | - <packing> |
879 | - <property name="expand">False</property> |
880 | - <property name="fill">False</property> |
881 | - <property name="position">0</property> |
882 | - </packing> |
883 | - </child> |
884 | - </object> |
885 | - <packing> |
886 | - <property name="expand">False</property> |
887 | - <property name="fill">True</property> |
888 | - <property name="position">0</property> |
889 | - </packing> |
890 | - </child> |
891 | - <child> |
892 | - <object class="GtkBox"> |
893 | - <property name="visible">True</property> |
894 | - <property name="can_focus">False</property> |
895 | - <property name="halign">start</property> |
896 | - <property name="border_width">12</property> |
897 | - <property name="spacing">18</property> |
898 | - <child> |
899 | - <object class="GtkImage"> |
900 | - <property name="visible">True</property> |
901 | - <property name="can_focus">False</property> |
902 | - <property name="halign">start</property> |
903 | - <property name="valign">start</property> |
904 | - <property name="icon_name">distributor-logo</property> |
905 | - <property name="icon_size">6</property> |
906 | - </object> |
907 | - <packing> |
908 | - <property name="expand">False</property> |
909 | - <property name="fill">False</property> |
910 | - <property name="position">0</property> |
911 | - </packing> |
912 | - </child> |
913 | - <child> |
914 | - <object class="GtkBox" id="box_auth"> |
915 | - <property name="visible">True</property> |
916 | - <property name="can_focus">False</property> |
917 | - <property name="halign">start</property> |
918 | - <property name="orientation">vertical</property> |
919 | - <property name="spacing">12</property> |
920 | - <child> |
921 | - <object class="GtkLabel" id="label_header"> |
922 | - <property name="name">label_header</property> |
923 | - <property name="visible">True</property> |
924 | - <property name="can_focus">False</property> |
925 | - <property name="halign">start</property> |
926 | - <property name="valign">start</property> |
927 | - <property name="use_markup">True</property> |
928 | - <property name="justify">fill</property> |
929 | - <property name="wrap">True</property> |
930 | - <property name="max_width_chars">40</property> |
931 | - </object> |
932 | - <packing> |
933 | - <property name="expand">False</property> |
934 | - <property name="fill">False</property> |
935 | - <property name="position">0</property> |
936 | - </packing> |
937 | - </child> |
938 | - <child> |
939 | - <object class="GtkComboBox" id="combobox_account"> |
940 | - <property name="can_focus">False</property> |
941 | - <property name="halign">start</property> |
942 | - <property name="model">liststore_account</property> |
943 | - <child> |
944 | - <object class="GtkCellRendererText"/> |
945 | - <attributes> |
946 | - <attribute name="text">1</attribute> |
947 | - </attributes> |
948 | - </child> |
949 | - </object> |
950 | - <packing> |
951 | - <property name="expand">False</property> |
952 | - <property name="fill">True</property> |
953 | - <property name="position">1</property> |
954 | - </packing> |
955 | - </child> |
956 | - <child> |
957 | - <object class="GtkLabel" id="label_account"> |
958 | - <property name="can_focus">False</property> |
959 | - <property name="halign">start</property> |
960 | - </object> |
961 | - <packing> |
962 | - <property name="expand">False</property> |
963 | - <property name="fill">True</property> |
964 | - <property name="position">2</property> |
965 | - </packing> |
966 | - </child> |
967 | - </object> |
968 | - <packing> |
969 | - <property name="expand">False</property> |
970 | - <property name="fill">False</property> |
971 | - <property name="position">1</property> |
972 | - </packing> |
973 | - </child> |
974 | - </object> |
975 | - <packing> |
976 | - <property name="expand">False</property> |
977 | - <property name="fill">False</property> |
978 | - <property name="position">1</property> |
979 | - </packing> |
980 | - </child> |
981 | - </object> |
982 | - </child> |
983 | - </template> |
984 | -</interface> |
985 | diff --git a/gnome-initial-setup/pages/livepatch/gis-livepatch-page.c b/gnome-initial-setup/pages/livepatch/gis-livepatch-page.c |
986 | deleted file mode 100644 |
987 | index eab2fb6..0000000 |
988 | --- a/gnome-initial-setup/pages/livepatch/gis-livepatch-page.c |
989 | +++ /dev/null |
990 | @@ -1,538 +0,0 @@ |
991 | -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ |
992 | -/* |
993 | - * Copyright (C) 2018 Canonical Ltd. |
994 | - * |
995 | - * This program is free software; you can redistribute it and/or |
996 | - * modify it under the terms of the GNU General Public License as |
997 | - * published by the Free Software Foundation; either version 2 of the |
998 | - * License, or (at your option) any later version. |
999 | - * |
1000 | - * This program is distributed in the hope that it will be useful, but |
1001 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
1002 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1003 | - * General Public License for more details. |
1004 | - * |
1005 | - * You should have received a copy of the GNU General Public License |
1006 | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
1007 | - * |
1008 | - * Written by: |
1009 | - * Andrea Azzarone <andrea.azzarone@canonical.com> |
1010 | - */ |
1011 | - |
1012 | -/* Canonical Livepatch page {{{1 */ |
1013 | - |
1014 | -#define PAGE_ID "livepatch" |
1015 | - |
1016 | -#include "config.h" |
1017 | -#include "gis-auth-dialog.h" |
1018 | -#include "gis-livepatch-page.h" |
1019 | -#include "livepatch-resources.h" |
1020 | - |
1021 | -#define GOA_API_IS_SUBJECT_TO_CHANGE |
1022 | -#include <goa/goa.h> |
1023 | -#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE |
1024 | -#include <goabackend/goabackend.h> |
1025 | - |
1026 | -#include <glib/gi18n.h> |
1027 | -#include <gio/gio.h> |
1028 | -#include <polkit/polkit.h> |
1029 | - |
1030 | -struct _GisLivepatchPagePrivate { |
1031 | - GtkWidget *setup_button; |
1032 | - GtkWidget *message_box; |
1033 | - GtkWidget *signout_button; |
1034 | - GtkWidget *message_label; |
1035 | - |
1036 | - GoaClient *goa_client; |
1037 | - GoaAccount *goa_account; |
1038 | - GPermission *permission; |
1039 | - |
1040 | - gchar *token; |
1041 | - gboolean waiting_for_livepatch_response; |
1042 | - gboolean user_current_choice; |
1043 | -}; |
1044 | -typedef struct _GisLivepatchPagePrivate GisLivepatchPagePrivate; |
1045 | - |
1046 | -G_DEFINE_TYPE_WITH_PRIVATE (GisLivepatchPage, gis_livepatch_page, GIS_TYPE_PAGE); |
1047 | - |
1048 | -#define LIVEPATCH_ENABLING_MESSAGE _("You're all set: Livepatch is now being enabled.") |
1049 | -#define LIVEPATCH_ENABLE_SUCCESS_MESSAGE _("You're all set: Livepatch is now on.") |
1050 | -#define LIVEPATCH_ENABLE_FAILURE_MESSAGE _("Failed to setup Livepatch: please retry.") |
1051 | -#define LIVEPATCH_DISABLE_FAILURE_MESSAGE _("Failed to disable Livepatch: please retry.") |
1052 | - |
1053 | -static gboolean |
1054 | -set_livepatch_enabled (GisLivepatchPage *page, |
1055 | - gboolean value); |
1056 | - |
1057 | -static gboolean |
1058 | -is_livepatch_enabled () |
1059 | -{ |
1060 | - return g_file_test ("/var/snap/canonical-livepatch/common/machine-token", |
1061 | - G_FILE_TEST_EXISTS); |
1062 | -} |
1063 | - |
1064 | -static char * |
1065 | -get_item (const char *buffer, const char *name) |
1066 | -{ |
1067 | - g_autofree gchar *label = NULL; |
1068 | - gchar *start = NULL, *end = NULL; |
1069 | - gchar end_char; |
1070 | - |
1071 | - label = g_strconcat (name, "=", NULL); |
1072 | - if ((start = strstr (buffer, label)) != NULL) { |
1073 | - start += strlen (label); |
1074 | - end_char = '\n'; |
1075 | - if (*start == '"') { |
1076 | - start++; |
1077 | - end_char = '"'; |
1078 | - } |
1079 | - end = strchr (start, end_char); |
1080 | - } |
1081 | - |
1082 | - if (start != NULL && end != NULL) |
1083 | - return g_strndup (start, end - start); |
1084 | - else |
1085 | - return NULL; |
1086 | -} |
1087 | - |
1088 | -static gboolean |
1089 | -is_lts () |
1090 | -{ |
1091 | - g_autofree gchar *buffer = NULL; |
1092 | - g_autofree gchar *version = NULL; |
1093 | - |
1094 | - if (g_file_get_contents ("/etc/os-release", &buffer, NULL, NULL)) |
1095 | - version = get_item (buffer, "VERSION"); |
1096 | - |
1097 | - return version && g_strrstr (version, "LTS") != NULL; |
1098 | -} |
1099 | - |
1100 | -static gboolean |
1101 | -is_livepatch_supported () |
1102 | -{ |
1103 | - return is_lts (); |
1104 | -} |
1105 | - |
1106 | -static void |
1107 | -open_software_properties () |
1108 | -{ |
1109 | - g_autofree gchar *command = NULL; |
1110 | - g_autoptr(GAppInfo) info = NULL; |
1111 | - g_autoptr(GError) error = NULL; |
1112 | - |
1113 | - info = g_app_info_create_from_commandline ("software-properties-gtk --open-tab=2", NULL, G_APP_INFO_CREATE_NONE, &error); |
1114 | - if (info == NULL) { |
1115 | - g_warning ("Failed to get launch information from software-properties-gtk: %s", error->message); |
1116 | - return; |
1117 | - } |
1118 | - |
1119 | - if (!g_app_info_launch (info, NULL, NULL, &error)) { |
1120 | - g_warning ("Failed to launch software-properties-gtk: %s", error->message); |
1121 | - return; |
1122 | - } |
1123 | -} |
1124 | - |
1125 | -static void |
1126 | -on_livepatch_enabled (GObject *source_object, |
1127 | - GAsyncResult *res, |
1128 | - gpointer data) |
1129 | -{ |
1130 | - GisLivepatchPage *page = GIS_LIVEPATCH_PAGE (data); |
1131 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1132 | - g_autoptr(GVariant) result = NULL; |
1133 | - gboolean success = TRUE; |
1134 | - gboolean current_state = is_livepatch_enabled (); |
1135 | - g_autofree gchar *out_message = NULL; |
1136 | - g_autoptr(GError) error = NULL; |
1137 | - |
1138 | - priv->waiting_for_livepatch_response = FALSE; |
1139 | - |
1140 | - result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); |
1141 | - if (result == NULL) { |
1142 | - g_warning ("Failed to enable/disable Livepatch through DBus: %s\n", error->message); |
1143 | - out_message = g_strdup (error->message); |
1144 | - success = FALSE; |
1145 | - } else { |
1146 | - gboolean out_error; |
1147 | - |
1148 | - g_variant_get (result, "(bs)", &out_error, &out_message); |
1149 | - if (out_error) { |
1150 | - g_warning ("Failed to enable/disable Livepatch: %s\n", out_message); |
1151 | - success = FALSE; |
1152 | - } |
1153 | - } |
1154 | - |
1155 | - if (success) { |
1156 | - /* We succeded to enable or disable livepatch. |
1157 | - Check if this corresponds to the current user choice. */ |
1158 | - if (current_state != priv->user_current_choice) { |
1159 | - set_livepatch_enabled (page, priv->user_current_choice); |
1160 | - } else if (current_state) { |
1161 | - gtk_label_set_text (GTK_LABEL (priv->message_label), LIVEPATCH_ENABLE_SUCCESS_MESSAGE); |
1162 | - } |
1163 | - } else if (current_state != priv->user_current_choice) { |
1164 | - GisAssistant *assistant = gis_driver_get_assistant (GIS_PAGE (page)->driver); |
1165 | - |
1166 | - /* We failed to enable or disable livepatch. Show an error message if |
1167 | - the current state does not correpond the current user choice. |
1168 | - Ignore the message if the call failed but the current status correponds |
1169 | - to the user choice. */ |
1170 | - if (priv->user_current_choice) { |
1171 | - gtk_label_set_text (GTK_LABEL (priv->message_label), LIVEPATCH_ENABLE_FAILURE_MESSAGE); |
1172 | - gtk_widget_set_sensitive (priv->setup_button, TRUE); |
1173 | - } else { |
1174 | - gtk_label_set_text (GTK_LABEL (priv->message_label), LIVEPATCH_DISABLE_FAILURE_MESSAGE); |
1175 | - } |
1176 | - |
1177 | - if (gis_assistant_get_current_page (assistant) != GIS_PAGE (page)) { |
1178 | - GtkWidget *dialog; |
1179 | - |
1180 | - dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))), |
1181 | - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, |
1182 | - GTK_MESSAGE_ERROR, |
1183 | - GTK_BUTTONS_NONE, |
1184 | - "<span font_size='x-large' font_weight='bold'>%s</span>", |
1185 | - _("Sorry there's been a problem with setting up Canonical Livepatch")); |
1186 | - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), |
1187 | - _("The error was: %s"), |
1188 | - out_message); |
1189 | - gtk_dialog_add_buttons (GTK_DIALOG (dialog), |
1190 | - _("Settings…"), |
1191 | - GTK_RESPONSE_OK, |
1192 | - _("Ignore"), |
1193 | - GTK_RESPONSE_CANCEL, |
1194 | - NULL); |
1195 | - |
1196 | - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) |
1197 | - open_software_properties (); |
1198 | - |
1199 | - gtk_widget_destroy (dialog); |
1200 | - } |
1201 | - } |
1202 | - |
1203 | - gis_driver_uninhibit_quit (GIS_PAGE (page)->driver); |
1204 | -} |
1205 | - |
1206 | -static gboolean |
1207 | -set_livepatch_enabled (GisLivepatchPage *page, |
1208 | - gboolean value) |
1209 | -{ |
1210 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1211 | - g_autoptr(GDBusProxy) proxy = NULL; |
1212 | - g_autoptr(GError) error = NULL; |
1213 | - GVariant *args; |
1214 | - |
1215 | - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, |
1216 | - G_DBUS_PROXY_FLAGS_NONE, |
1217 | - NULL, /* info */ |
1218 | - "com.ubuntu.SoftwareProperties", |
1219 | - "/", |
1220 | - "com.ubuntu.SoftwareProperties", |
1221 | - NULL, /* cancellable */ |
1222 | - &error); |
1223 | - |
1224 | - if (proxy == NULL) { |
1225 | - g_warning ("Failed to get dbus proxy for com.ubuntu.SoftwareProperties: %s", error->message); |
1226 | - return FALSE; |
1227 | - } |
1228 | - |
1229 | - if (value) { |
1230 | - args = g_variant_new ("(bs)", TRUE, priv->token); |
1231 | - } else { |
1232 | - args = g_variant_new ("(bs)", FALSE, ""); |
1233 | - } |
1234 | - |
1235 | - gis_driver_inhibit_quit (GIS_PAGE (page)->driver); |
1236 | - priv->waiting_for_livepatch_response = TRUE; |
1237 | - g_dbus_proxy_call (proxy, |
1238 | - "SetLivepatchEnabled", |
1239 | - args, |
1240 | - /* Fallback to interactive authorization if the meta action didn't work */ |
1241 | - G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION, |
1242 | - 1200000, /* 20 minutes timeout should be enough to install and enable livepatch */ |
1243 | - NULL, /* cancellable */ |
1244 | - on_livepatch_enabled, |
1245 | - page); |
1246 | - |
1247 | - return TRUE; |
1248 | -} |
1249 | - |
1250 | -static void |
1251 | -on_livepatch_token_ready (GObject *source_object, |
1252 | - GAsyncResult *res, |
1253 | - gpointer data) |
1254 | -{ |
1255 | - GisLivepatchPage *page = GIS_LIVEPATCH_PAGE (data); |
1256 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1257 | - GoaPasswordBased *password_based = GOA_PASSWORD_BASED (source_object); |
1258 | - g_autoptr(GError) error = NULL; |
1259 | - |
1260 | - if (!goa_password_based_call_get_password_finish (password_based, &priv->token, res, &error)) { |
1261 | - g_warning ("Failed to get livepatch token: %s", error->message); |
1262 | - gtk_widget_set_sensitive (priv->setup_button, TRUE); |
1263 | - return; |
1264 | - } |
1265 | - |
1266 | - priv->user_current_choice = TRUE; |
1267 | - gtk_widget_set_visible (priv->message_box, TRUE); |
1268 | - if (set_livepatch_enabled (page, TRUE)) { |
1269 | - gtk_label_set_text (GTK_LABEL (priv->message_label), LIVEPATCH_ENABLING_MESSAGE); |
1270 | - } else { |
1271 | - gtk_label_set_text (GTK_LABEL (priv->message_label), LIVEPATCH_ENABLE_FAILURE_MESSAGE); |
1272 | - gtk_widget_set_sensitive (priv->setup_button, TRUE); |
1273 | - } |
1274 | -} |
1275 | - |
1276 | -static void |
1277 | -goa_account_store (const gchar *account_id) |
1278 | -{ |
1279 | - GSettingsSchemaSource *source; |
1280 | - g_autoptr(GSettingsSchema) schema = NULL; |
1281 | - g_autoptr(GSettings) settings = NULL; |
1282 | - |
1283 | - /* Check if the gsettings schema is installed */ |
1284 | - source = g_settings_schema_source_get_default (); |
1285 | - if (!source) |
1286 | - return; |
1287 | - schema = g_settings_schema_source_lookup (source, "com.ubuntu.SoftwareProperties", TRUE); |
1288 | - if (!schema) |
1289 | - return; |
1290 | - |
1291 | - /* If the schema is installed... */ |
1292 | - settings = g_settings_new ("com.ubuntu.SoftwareProperties"); |
1293 | - g_settings_set_string (settings, "goa-account-id", account_id); |
1294 | -} |
1295 | - |
1296 | -static void |
1297 | -login_and_enable_livepatch (GisLivepatchPage *page) |
1298 | -{ |
1299 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1300 | - g_autofree gchar *account_id = NULL; |
1301 | - GoaObject *goa_object = NULL; |
1302 | - GoaPasswordBased *password_based = NULL; |
1303 | - GtkWidget *dialog = NULL; |
1304 | - g_autoptr(GError) error = NULL; |
1305 | - |
1306 | - /* show the login dialog if needed */ |
1307 | - dialog = gis_auth_dialog_new (&error); |
1308 | - if (dialog) { |
1309 | - gtk_window_set_transient_for (GTK_WINDOW (dialog), |
1310 | - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page)))); |
1311 | - |
1312 | - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { |
1313 | - account_id = gis_auth_dialog_get_account_id (GIS_AUTH_DIALOG (dialog)); |
1314 | - goa_object = goa_client_lookup_by_id (priv->goa_client, account_id); |
1315 | - } |
1316 | - } else { |
1317 | - g_warning ("Failed to create the authentication dialog: %s\n", error->message); |
1318 | - } |
1319 | - |
1320 | - /* login dialog was dismissed */ |
1321 | - if (goa_object == NULL) { |
1322 | - gtk_widget_set_sensitive (priv->setup_button, TRUE); |
1323 | - goto out; |
1324 | - } |
1325 | - |
1326 | - priv->goa_account = goa_object_get_account (goa_object); |
1327 | - goa_account_store (account_id); |
1328 | - |
1329 | - /* retrieve livepatch token */ |
1330 | - password_based = goa_object_peek_password_based (goa_object); |
1331 | - |
1332 | - goa_password_based_call_get_password (password_based, |
1333 | - "livepatch", |
1334 | - NULL /* cancellable */, |
1335 | - on_livepatch_token_ready, |
1336 | - page); |
1337 | - out: |
1338 | - g_clear_pointer (&dialog, gtk_widget_destroy); |
1339 | - g_clear_object (&goa_object); |
1340 | -} |
1341 | - |
1342 | -static void |
1343 | -on_livepatch_permission_acquired (GObject *source, |
1344 | - GAsyncResult *res, |
1345 | - gpointer data) |
1346 | -{ |
1347 | - GisLivepatchPage *page = GIS_LIVEPATCH_PAGE (data); |
1348 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1349 | - g_autoptr(GError) error = NULL; |
1350 | - gboolean allowed; |
1351 | - |
1352 | - allowed = g_permission_acquire_finish (priv->permission, res, &error); |
1353 | - if (error) { |
1354 | - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) |
1355 | - g_warning ("Failed to acquire permission: %s", error->message); |
1356 | - else |
1357 | - gtk_widget_set_sensitive (priv->setup_button, TRUE); |
1358 | - return; |
1359 | - } |
1360 | - |
1361 | - if (allowed) |
1362 | - login_and_enable_livepatch (page); |
1363 | -} |
1364 | - |
1365 | -static void |
1366 | -on_setup_button_clicked (GtkButton *button, |
1367 | - gpointer data) |
1368 | -{ |
1369 | - GisLivepatchPage *page = GIS_LIVEPATCH_PAGE (data); |
1370 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1371 | - |
1372 | - gtk_widget_set_sensitive (priv->setup_button, FALSE); |
1373 | - |
1374 | - if (G_IS_PERMISSION (priv->permission) && g_permission_get_allowed (priv->permission)) { |
1375 | - login_and_enable_livepatch (page); |
1376 | - } |
1377 | - else if (G_IS_PERMISSION (priv->permission) && g_permission_get_can_acquire (priv->permission)) { |
1378 | - g_permission_acquire_async (priv->permission, |
1379 | - NULL, |
1380 | - on_livepatch_permission_acquired, |
1381 | - page); |
1382 | - } else { |
1383 | - g_warning ("Could not start the attempt to acquire the permission to enable Livepatch. Fallback to per-app policy."); |
1384 | - login_and_enable_livepatch (page); |
1385 | - } |
1386 | -} |
1387 | - |
1388 | -static void |
1389 | -on_signout_button_clicked (GtkButton *button, |
1390 | - GisLivepatchPage *page) |
1391 | -{ |
1392 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1393 | - |
1394 | - /* disable livepatch */ |
1395 | - priv->user_current_choice = FALSE; |
1396 | - if (!priv->waiting_for_livepatch_response && is_livepatch_enabled ()) |
1397 | - set_livepatch_enabled (page, FALSE); |
1398 | - |
1399 | - goa_account_store (""); |
1400 | - /* remove GoaAccount from system */ |
1401 | - goa_account_call_remove (priv->goa_account, NULL, NULL, NULL); |
1402 | - |
1403 | - /* reset the GUI */ |
1404 | - gtk_widget_set_sensitive (priv->setup_button, TRUE); |
1405 | - gtk_widget_set_visible (priv->message_box, FALSE); |
1406 | - |
1407 | - g_clear_object (&priv->goa_account); |
1408 | - g_clear_pointer (&priv->token, g_free); |
1409 | -} |
1410 | - |
1411 | -static void |
1412 | -show_legal (GtkButton *button, GisLivepatchPage *page) |
1413 | -{ |
1414 | - g_autofree gchar *buffer = NULL; |
1415 | - g_autofree gchar *privacy_policy = NULL; |
1416 | - g_autoptr(GError) error = NULL; |
1417 | - |
1418 | - if (g_file_get_contents ("/etc/os-release", &buffer, NULL, NULL)) |
1419 | - privacy_policy = get_item (buffer, "PRIVACY_POLICY_URL"); |
1420 | - |
1421 | - if (!gtk_show_uri_on_window (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))), |
1422 | - privacy_policy, |
1423 | - GDK_CURRENT_TIME, &error)) { |
1424 | - GtkWidget *dialog; |
1425 | - dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))), |
1426 | - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, |
1427 | - GTK_MESSAGE_ERROR, |
1428 | - GTK_BUTTONS_CLOSE, |
1429 | - _("Failed to show Livepatch policy: %s"), error->message); |
1430 | - gtk_dialog_run (GTK_DIALOG (dialog)); |
1431 | - gtk_widget_destroy (dialog); |
1432 | - return; |
1433 | - } |
1434 | -} |
1435 | - |
1436 | -static void |
1437 | -gis_livepatch_page_constructed (GObject *object) |
1438 | -{ |
1439 | - GisLivepatchPage *page = GIS_LIVEPATCH_PAGE (object); |
1440 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1441 | - g_autoptr(GError) error = NULL; |
1442 | - |
1443 | - G_OBJECT_CLASS (gis_livepatch_page_parent_class)->constructed (object); |
1444 | - |
1445 | - gis_page_set_skippable (GIS_PAGE (page), TRUE); |
1446 | - |
1447 | - priv->goa_client = goa_client_new_sync (NULL, &error); |
1448 | - |
1449 | - if (priv->goa_client == NULL) { |
1450 | - g_error ("Failed to get a GoaClient: %s", error->message); |
1451 | - return; |
1452 | - } |
1453 | - |
1454 | - priv->permission = polkit_permission_new_sync ("com.ubuntu.welcome.livepatch", NULL, NULL, &error); |
1455 | - if (priv->permission == NULL) { |
1456 | - g_warning ("Could not get 'com.ubuntu.welcome.livepatch' permission: %s", |
1457 | - error->message); |
1458 | - } |
1459 | - |
1460 | - g_signal_connect (priv->setup_button, "clicked", |
1461 | - G_CALLBACK (on_setup_button_clicked), page); |
1462 | - |
1463 | - g_signal_connect (priv->signout_button, "clicked", |
1464 | - G_CALLBACK (on_signout_button_clicked), page); |
1465 | - |
1466 | - gis_page_set_complete (GIS_PAGE (page), TRUE); |
1467 | - gtk_widget_show (GTK_WIDGET (page)); |
1468 | -} |
1469 | - |
1470 | -static void |
1471 | -gis_livepatch_page_dispose (GObject *object) |
1472 | -{ |
1473 | - GisLivepatchPage *page = GIS_LIVEPATCH_PAGE (object); |
1474 | - GisLivepatchPagePrivate *priv = gis_livepatch_page_get_instance_private (page); |
1475 | - |
1476 | - g_clear_object (&priv->goa_client); |
1477 | - g_clear_object (&priv->goa_account); |
1478 | - g_clear_object (&priv->permission); |
1479 | - g_clear_pointer (&priv->token, g_free); |
1480 | - |
1481 | - G_OBJECT_CLASS (gis_livepatch_page_parent_class)->dispose (object); |
1482 | -} |
1483 | - |
1484 | -static void |
1485 | -gis_livepatch_page_locale_changed (GisPage *page) |
1486 | -{ |
1487 | - gis_page_set_title (GIS_PAGE (page), _("Livepatch")); |
1488 | -} |
1489 | - |
1490 | -static void |
1491 | -gis_livepatch_page_class_init (GisLivepatchPageClass *klass) |
1492 | -{ |
1493 | - GisPageClass *page_class = GIS_PAGE_CLASS (klass); |
1494 | - GObjectClass *object_class = G_OBJECT_CLASS (klass); |
1495 | - |
1496 | - gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-livepatch-page.ui"); |
1497 | - |
1498 | - gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLivepatchPage, setup_button); |
1499 | - gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLivepatchPage, message_box); |
1500 | - gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLivepatchPage, signout_button); |
1501 | - gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLivepatchPage, message_label); |
1502 | - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), show_legal); |
1503 | - |
1504 | - |
1505 | - page_class->page_id = PAGE_ID; |
1506 | - page_class->locale_changed = gis_livepatch_page_locale_changed; |
1507 | - object_class->constructed = gis_livepatch_page_constructed; |
1508 | - object_class->dispose = gis_livepatch_page_dispose; |
1509 | -} |
1510 | - |
1511 | -static void |
1512 | -gis_livepatch_page_init (GisLivepatchPage *page) |
1513 | -{ |
1514 | - g_resources_register (livepatch_get_resource ()); |
1515 | - |
1516 | - gtk_widget_init_template (GTK_WIDGET (page)); |
1517 | -} |
1518 | - |
1519 | -GisPage * |
1520 | -gis_prepare_livepatch_page (GisDriver *driver) |
1521 | -{ |
1522 | - if (is_livepatch_enabled () || !is_livepatch_supported ()) |
1523 | - return NULL; |
1524 | - |
1525 | - return g_object_new (GIS_TYPE_LIVEPATCH_PAGE, |
1526 | - "driver", driver, |
1527 | - NULL); |
1528 | -} |
1529 | diff --git a/gnome-initial-setup/pages/livepatch/gis-livepatch-page.h b/gnome-initial-setup/pages/livepatch/gis-livepatch-page.h |
1530 | deleted file mode 100644 |
1531 | index 3356dbe..0000000 |
1532 | --- a/gnome-initial-setup/pages/livepatch/gis-livepatch-page.h |
1533 | +++ /dev/null |
1534 | @@ -1,52 +0,0 @@ |
1535 | -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ |
1536 | -/* |
1537 | - * Copyright (C) 2018 Canonical Ltd. |
1538 | - * |
1539 | - * This program is free software; you can redistribute it and/or |
1540 | - * modify it under the terms of the GNU General Public License as |
1541 | - * published by the Free Software Foundation; either version 2 of the |
1542 | - * License, or (at your option) any later version. |
1543 | - * |
1544 | - * This program is distributed in the hope that it will be useful, but |
1545 | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
1546 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1547 | - * General Public License for more details. |
1548 | - * |
1549 | - * You should have received a copy of the GNU General Public License |
1550 | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
1551 | - */ |
1552 | - |
1553 | -#ifndef __GIS_LIVEPATCH_PAGE_H__ |
1554 | -#define __GIS_LIVEPATCH_PAGE_H__ |
1555 | - |
1556 | -#include "gnome-initial-setup.h" |
1557 | - |
1558 | -G_BEGIN_DECLS |
1559 | - |
1560 | -#define GIS_TYPE_LIVEPATCH_PAGE (gis_livepatch_page_get_type ()) |
1561 | -#define GIS_LIVEPATCH_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_LIVEPATCH_PAGE, GisLivepatchPage)) |
1562 | -#define GIS_LIVEPATCH_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_LIVEPATCH_PAGE, GisLivepatchPageClass)) |
1563 | -#define GIS_IS_LIVEPATCH_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_LIVEPATCH_PAGE)) |
1564 | -#define GIS_IS_LIVEPATCH_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_LIVEPATCH_PAGE)) |
1565 | -#define GIS_LIVEPATCH_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_LIVEPATCH_PAGE, GisLivepatchPageClass)) |
1566 | - |
1567 | -typedef struct _GisLivepatchPage GisLivepatchPage; |
1568 | -typedef struct _GisLivepatchPageClass GisLivepatchPageClass; |
1569 | - |
1570 | -struct _GisLivepatchPage |
1571 | -{ |
1572 | - GisPage parent; |
1573 | -}; |
1574 | - |
1575 | -struct _GisLivepatchPageClass |
1576 | -{ |
1577 | - GisPageClass parent_class; |
1578 | -}; |
1579 | - |
1580 | -GType gis_livepatch_page_get_type (void); |
1581 | - |
1582 | -GisPage *gis_prepare_livepatch_page (GisDriver *driver); |
1583 | - |
1584 | -G_END_DECLS |
1585 | - |
1586 | -#endif /* __GIS_LIVEPATCH_PAGE_H__ */ |
1587 | diff --git a/gnome-initial-setup/pages/livepatch/gis-livepatch-page.ui b/gnome-initial-setup/pages/livepatch/gis-livepatch-page.ui |
1588 | deleted file mode 100644 |
1589 | index c877ff5..0000000 |
1590 | --- a/gnome-initial-setup/pages/livepatch/gis-livepatch-page.ui |
1591 | +++ /dev/null |
1592 | @@ -1,156 +0,0 @@ |
1593 | -<?xml version="1.0" encoding="UTF-8"?> |
1594 | -<interface> |
1595 | - <!-- interface-requires gtk+ 3.0 --> |
1596 | - <template class="GisLivepatchPage" parent="GisPage"> |
1597 | - <child> |
1598 | - <object class="GtkGrid"> |
1599 | - <property name="visible">True</property> |
1600 | - <property name="can_focus">False</property> |
1601 | - <property name="row_spacing">40</property> |
1602 | - <property name="border_width">20</property> |
1603 | - <child> |
1604 | - <object class="GtkLabel" id="title"> |
1605 | - <property name="visible">True</property> |
1606 | - <property name="can_focus">False</property> |
1607 | - <property name="halign">start</property> |
1608 | - <property name="valign">start</property> |
1609 | - <property name="label" translatable="yes">Livepatch</property> |
1610 | - <attributes> |
1611 | - <attribute name="weight" value="bold"/> |
1612 | - <attribute name="scale" value="1.8"/> |
1613 | - </attributes> |
1614 | - </object> |
1615 | - <packing> |
1616 | - <property name="left_attach">0</property> |
1617 | - <property name="top_attach">0</property> |
1618 | - <property name="width">3</property> |
1619 | - <property name="height">1</property> |
1620 | - </packing> |
1621 | - </child> |
1622 | - <child> |
1623 | - <object class="GtkImage" id="icon_image"> |
1624 | - <property name="visible">True</property> |
1625 | - <property name="can_focus">False</property> |
1626 | - <property name="valign">start</property> |
1627 | - <property name="halign">start</property> |
1628 | - <property name="resource">/org/gnome/initial-setup/livepatch.svg</property> |
1629 | - </object> |
1630 | - <packing> |
1631 | - <property name="left_attach">0</property> |
1632 | - <property name="top_attach">1</property> |
1633 | - <property name="width">1</property> |
1634 | - <property name="height">1</property> |
1635 | - </packing> |
1636 | - </child> |
1637 | - <child> |
1638 | - <object class="GtkLabel" id="right_padding_label"> |
1639 | - <property name="visible">True</property> |
1640 | - </object> |
1641 | - <packing> |
1642 | - <property name="left_attach">2</property> |
1643 | - <property name="top_attach">1</property> |
1644 | - <property name="width">1</property> |
1645 | - <property name="height">1</property> |
1646 | - </packing> |
1647 | - </child> |
1648 | - <child> |
1649 | - <object class="GtkBox"> |
1650 | - <property name="visible">True</property> |
1651 | - <property name="can_focus">False</property> |
1652 | - <property name="halign">center</property> |
1653 | - <property name="hexpand">True</property> |
1654 | - <property name="valign">start</property> |
1655 | - <property name="vexpand">True</property> |
1656 | - <property name="orientation">vertical</property> |
1657 | - <child> |
1658 | - <object class="GtkLabel"> |
1659 | - <property name="visible">True</property> |
1660 | - <property name="can_focus">False</property> |
1661 | - <property name="max-width-chars">50</property> |
1662 | - <property name="xalign">0</property> |
1663 | - <property name="halign">start</property> |
1664 | - <property name="label" translatable="yes">Canonical Livepatch helps keep your computer secure, by applying some updates that would normally require restarting.</property> |
1665 | - <property name="wrap">True</property> |
1666 | - </object> |
1667 | - </child> |
1668 | - <child> |
1669 | - <object class="GtkLabel"> |
1670 | - <property name="visible">True</property> |
1671 | - <property name="xalign">0</property> |
1672 | - <property name="margin_top">18</property> |
1673 | - <property name="label" translatable="yes">Would you like to set up Livepatch now?</property> |
1674 | - <attributes> |
1675 | - <attribute name="weight" value="bold"/> |
1676 | - </attributes> |
1677 | - </object> |
1678 | - </child> |
1679 | - <child> |
1680 | - <object class="GtkBox"> |
1681 | - <property name="visible">True</property> |
1682 | - <property name="can_focus">False</property> |
1683 | - <property name="halign">start</property> |
1684 | - <property name="orientation">horizontal</property> |
1685 | - <property name="margin_top">18</property> |
1686 | - <property name="spacing">6</property> |
1687 | - <child> |
1688 | - <object class="GtkButton" id="setup_button"> |
1689 | - <property name="visible">True</property> |
1690 | - <property name="halign">start</property> |
1691 | - <property name="label" translatable="yes">Set Up Livepatch…</property> |
1692 | - <style> |
1693 | - <class name="suggested-action"/> |
1694 | - </style> |
1695 | - </object> |
1696 | - </child> |
1697 | - <child> |
1698 | - <object class="GtkButton"> |
1699 | - <property name="visible">True</property> |
1700 | - <property name="label" translatable="yes">Legal notice</property> |
1701 | - <signal name="clicked" handler="show_legal"/> |
1702 | - </object> |
1703 | - </child> |
1704 | - </object> |
1705 | - </child> |
1706 | - <child> |
1707 | - <object class="GtkBox" id="message_box"> |
1708 | - <property name="visible">False</property> |
1709 | - <property name="can_focus">False</property> |
1710 | - <property name="halign">fill</property> |
1711 | - <property name="orientation">horizontal</property> |
1712 | - <property name="margin_top">18</property> |
1713 | - <child> |
1714 | - <object class="GtkLabel" id="message_label"> |
1715 | - <property name="visible">True</property> |
1716 | - <property name="xalign">0</property> |
1717 | - </object> |
1718 | - </child> |
1719 | - <child> |
1720 | - <object class="GtkButton" id="signout_button"> |
1721 | - <property name="visible">True</property> |
1722 | - <property name="label" translatable="yes">Sign Out</property> |
1723 | - </object> |
1724 | - <packing> |
1725 | - <property name="pack-type">end</property> |
1726 | - </packing> |
1727 | - </child> |
1728 | - </object> |
1729 | - </child> |
1730 | - </object> |
1731 | - <packing> |
1732 | - <property name="left_attach">1</property> |
1733 | - <property name="top_attach">1</property> |
1734 | - <property name="width">1</property> |
1735 | - <property name="height">1</property> |
1736 | - </packing> |
1737 | - </child> |
1738 | - </object> |
1739 | - </child> |
1740 | - </template> |
1741 | - <object class="GtkSizeGroup"> |
1742 | - <property name="mode">horizontal</property> |
1743 | - <widgets> |
1744 | - <widget name="icon_image"/> |
1745 | - <widget name="right_padding_label"/> |
1746 | - </widgets> |
1747 | - </object> |
1748 | -</interface> |
1749 | diff --git a/gnome-initial-setup/pages/livepatch/livepatch.gresource.xml b/gnome-initial-setup/pages/livepatch/livepatch.gresource.xml |
1750 | deleted file mode 100644 |
1751 | index 5678958..0000000 |
1752 | --- a/gnome-initial-setup/pages/livepatch/livepatch.gresource.xml |
1753 | +++ /dev/null |
1754 | @@ -1,9 +0,0 @@ |
1755 | -<?xml version="1.0" encoding="UTF-8"?> |
1756 | -<gresources> |
1757 | - <gresource prefix="/org/gnome/initial-setup"> |
1758 | - <file preprocess="xml-stripblanks" alias="gis-livepatch-page.ui">gis-livepatch-page.ui</file> |
1759 | - <file preprocess="xml-stripblanks" alias="gis-auth-dialog.ui">gis-auth-dialog.ui</file> |
1760 | - <file alias="livepatch.svg">livepatch.svg</file> |
1761 | - </gresource> |
1762 | -</gresources> |
1763 | - |
1764 | diff --git a/gnome-initial-setup/pages/livepatch/livepatch.svg b/gnome-initial-setup/pages/livepatch/livepatch.svg |
1765 | deleted file mode 100644 |
1766 | index a84bcd6..0000000 |
1767 | --- a/gnome-initial-setup/pages/livepatch/livepatch.svg |
1768 | +++ /dev/null |
1769 | @@ -1 +0,0 @@ |
1770 | -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" x="0px" y="0px" width="150px" height="150px" viewBox="0 0 400 400" style="enable-background:new 0 0 400 400;" xml:space="preserve"> <style type="text/css"> .st0{fill:#666666; fill-opacity:0.25;} </style> <g> <path class="st0" d="M73.7,168.4c0-69.7,56.7-126.3,126.3-126.3c69.7,0,126.3,56.7,126.3,126.3h42.1C368.4,75.6,292.9,0,200,0 C107.1,0,31.6,75.6,31.6,168.4v63.7h0C31.9,324.8,107.3,400,200,400c92.9,0,168.4-75.6,168.4-168.4v-21.1H73.7V168.4L73.7,168.4z M200,242.1c17.4,0,31.6,14.1,31.6,31.6c0,13.7-8.8,25.4-21,29.7v54.4c0,5.8-4.7,10.5-10.5,10.5s-10.5-4.7-10.5-10.5v-54.4 c-12.3-4.3-21.1-16-21.1-29.8C168.4,256.3,182.6,242.1,200,242.1L200,242.1z"/> </g> </svg> |
1771 | diff --git a/gnome-initial-setup/pages/livepatch/meson.build b/gnome-initial-setup/pages/livepatch/meson.build |
1772 | deleted file mode 100644 |
1773 | index 14d89ed..0000000 |
1774 | --- a/gnome-initial-setup/pages/livepatch/meson.build |
1775 | +++ /dev/null |
1776 | @@ -1,12 +0,0 @@ |
1777 | -sources += gnome.compile_resources( |
1778 | - 'livepatch-resources', |
1779 | - files('livepatch.gresource.xml'), |
1780 | - c_name: 'livepatch' |
1781 | -) |
1782 | - |
1783 | -sources += files( |
1784 | - 'gis-livepatch-page.c', |
1785 | - 'gis-livepatch-page.h', |
1786 | - 'gis-auth-dialog.c', |
1787 | - 'gis-auth-dialog.h', |
1788 | -) |
1789 | diff --git a/gnome-initial-setup/pages/meson.build b/gnome-initial-setup/pages/meson.build |
1790 | index 32f615b..2767094 100644 |
1791 | --- a/gnome-initial-setup/pages/meson.build |
1792 | +++ b/gnome-initial-setup/pages/meson.build |
1793 | @@ -10,8 +10,8 @@ pages = [ |
1794 | 'software', |
1795 | 'summary', |
1796 | 'welcome', |
1797 | + 'ubuntu-pro', |
1798 | 'ubuntu-report', |
1799 | - 'livepatch', |
1800 | 'apps', |
1801 | ] |
1802 | |
1803 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/checkmark.svg b/gnome-initial-setup/pages/ubuntu-pro/checkmark.svg |
1804 | new file mode 100644 |
1805 | index 0000000..a0c8602 |
1806 | --- /dev/null |
1807 | +++ b/gnome-initial-setup/pages/ubuntu-pro/checkmark.svg |
1808 | @@ -0,0 +1 @@ |
1809 | +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="none" fill-rule="nonzero"><path fill="#0e8420" d="M8 1a7 7 0 110 14A7 7 0 018 1zm2.83 3.502L6.863 9.884 5.174 8.096l-1.09 1.03 2.92 3.096 5.034-6.83-1.208-.89z"/><path fill="#fff" d="M10.83 4.502l1.208.89-5.033 6.83-2.922-3.096 1.091-1.03 1.689 1.789z"/></g></svg> |
1810 | \ No newline at end of file |
1811 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/fail.svg b/gnome-initial-setup/pages/ubuntu-pro/fail.svg |
1812 | new file mode 100644 |
1813 | index 0000000..e3c9a52 |
1814 | --- /dev/null |
1815 | +++ b/gnome-initial-setup/pages/ubuntu-pro/fail.svg |
1816 | @@ -0,0 +1 @@ |
1817 | +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><defs><filter id="darkreader-image-filter"><feColorMatrix type="matrix" values="-0.193 -0.490 -1.120 0.000 1.698 -0.965 0.293 -1.105 0.000 1.673 -0.946 -0.489 -0.296 0.000 1.630 0.000 0.000 0.000 1.000 0.000"/></filter></defs><image width="16" height="16" filter="url(#darkreader-image-filter)" xlink:href="data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Ccircle stroke='%23c7162b' stroke-width='1.5' fill='%23c7162b' cx='8' cy='8' r='6.25'/%3E%3Cpath fill='%23FFF' fill-rule='nonzero' d='M10.282 4.638l1.06 1.06L9.05 7.99l2.293 2.292-1.06 1.06L7.99 9.05 5.7 11.343l-1.06-1.06 2.29-2.293L4.64 5.7l1.06-1.06 2.291 2.29z'/%3E%3C/g%3E%3C/svg%3E"/></svg> |
1818 | \ No newline at end of file |
1819 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-attach-page.ui b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-attach-page.ui |
1820 | new file mode 100644 |
1821 | index 0000000..930d4b7 |
1822 | --- /dev/null |
1823 | +++ b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-attach-page.ui |
1824 | @@ -0,0 +1,214 @@ |
1825 | +<?xml version="1.0" encoding="UTF-8"?> |
1826 | +<interface> |
1827 | + <!-- interface-requires gtk+ 3.0 --> |
1828 | + <template class="GisUbuntuProAttachPage" parent="GtkBin"> |
1829 | + <child> |
1830 | + <object class="GtkBox" id="attach_page"> |
1831 | + <property name="visible">True</property> |
1832 | + <property name="can-focus">False</property> |
1833 | + <property name="no-show-all">True</property> |
1834 | + <property name="orientation">vertical</property> |
1835 | + <child> |
1836 | + <object class="GtkLabel"> |
1837 | + <property name="visible">True</property> |
1838 | + <property name="can-focus">False</property> |
1839 | + <property name="halign">start</property> |
1840 | + <property name="margin-top">3</property> |
1841 | + <property name="margin-bottom">0</property> |
1842 | + <property name="label" translatable="yes"><b>Enable Ubuntu Pro</b></property> |
1843 | + <property name="use-markup">True</property> |
1844 | + <property name="wrap">True</property> |
1845 | + <property name="xalign">0</property> |
1846 | + <attributes> |
1847 | + <attribute name="scale" value="1.4"/> |
1848 | + </attributes> |
1849 | + </object> |
1850 | + </child> |
1851 | + <child> |
1852 | + <object class="GtkSeparator"> |
1853 | + <property name="visible">True</property> |
1854 | + <property name="can-focus">False</property> |
1855 | + <property name="margin-top">10</property> |
1856 | + <property name="margin-bottom">10</property> |
1857 | + </object> |
1858 | + </child> |
1859 | + <child> |
1860 | + <object class="GtkEventBox"> |
1861 | + <property name="visible">True</property> |
1862 | + <property name="can-focus">False</property> |
1863 | + <property name="margin-top">12</property> |
1864 | + <property name="margin-bottom">12</property> |
1865 | + <child> |
1866 | + <object class="GtkBox"> |
1867 | + <property name="visible">True</property> |
1868 | + <property name="can-focus">False</property> |
1869 | + <child> |
1870 | + <object class="GtkImage" id="ubuntu_pro_logo"> |
1871 | + <property name="visible">True</property> |
1872 | + <property name="can-focus">False</property> |
1873 | + <property name="margin-left">30</property> |
1874 | + <property name="margin-right">30</property> |
1875 | + <property name="yalign">0</property> |
1876 | + </object> |
1877 | + </child> |
1878 | + <child> |
1879 | + <object class="GtkLabel"> |
1880 | + <property name="visible">True</property> |
1881 | + <property name="can-focus">True</property> |
1882 | + <property name="margin-right">30</property> |
1883 | + <property name="label" translatable="yes">Upgrade this machine to Ubuntu Pro for security updates on a much wider range of packages, until 2032. Fulfill FedRAMP, FIPS, STIG and HIPAA and other compliance and hardening requirements with certified tooling and crypto-modules. Free up to 5 machines. |
1884 | + |
1885 | +More information on <a href="https://ubuntu.com/pro">ubuntu.com/pro</a>.</property> |
1886 | + <property name="use-markup">True</property> |
1887 | + <property name="wrap">True</property> |
1888 | + <property name="max-width-chars">130</property> |
1889 | + </object> |
1890 | + </child> |
1891 | + </object> |
1892 | + </child> |
1893 | + </object> |
1894 | + </child> |
1895 | + <child> |
1896 | + <object class="GtkRadioButton" id="magic_radio"> |
1897 | + <property name="label" translatable="yes">Enter code on ubuntu.com/pro/attach</property> |
1898 | + <property name="visible">True</property> |
1899 | + <property name="can-focus">True</property> |
1900 | + <property name="receives-default">False</property> |
1901 | + <property name="margin-top">40</property> |
1902 | + <property name="margin-bottom">6</property> |
1903 | + <property name="margin-left">30</property> |
1904 | + <property name="xalign">0</property> |
1905 | + <property name="group">magic_radio</property> |
1906 | + <signal name="clicked" handler="on_magic_clicked" swapped="no"/> |
1907 | + </object> |
1908 | + </child> |
1909 | + <child> |
1910 | + <object class="GtkBox"> |
1911 | + <property name="visible">True</property> |
1912 | + <property name="can-focus">False</property> |
1913 | + <property name="margin-left">30</property> |
1914 | + <child> |
1915 | + <object class="GtkLabel" id="pin_label"> |
1916 | + <property name="selectable">True</property> |
1917 | + <property name="visible">True</property> |
1918 | + <property name="can-focus">False</property> |
1919 | + <property name="margin-top">8</property> |
1920 | + <property name="margin-bottom">8</property> |
1921 | + <property name="halign">start</property> |
1922 | + <property name="margin-left">32</property> |
1923 | + <attributes> |
1924 | + <attribute name="scale" value="2"/> |
1925 | + </attributes> |
1926 | + </object> |
1927 | + </child> |
1928 | + <child> |
1929 | + <object class="GtkFixed"> |
1930 | + <property name="visible">True</property> |
1931 | + <property name="valign">center</property> |
1932 | + <property name="margin-left">12</property> |
1933 | + <property name="margin-right">6</property> |
1934 | + <child> |
1935 | + <object class="GtkSpinner" id="pin_spinner"> |
1936 | + <property name="visible">True</property> |
1937 | + <property name="valign">center</property> |
1938 | + </object> |
1939 | + </child> |
1940 | + <child> |
1941 | + <object class="GtkImage" id="pin_status_icon"> |
1942 | + <property name="visible">False</property> |
1943 | + <property name="valign">center</property> |
1944 | + </object> |
1945 | + </child> |
1946 | + </object> |
1947 | + </child> |
1948 | + <child> |
1949 | + <object class="GtkLabel" id="pin_status"> |
1950 | + <property name="visible">True</property> |
1951 | + <property name="use-markup">True</property> |
1952 | + <property name="halign">start</property> |
1953 | + </object> |
1954 | + </child> |
1955 | + </object> |
1956 | + </child> |
1957 | + <child> |
1958 | + <object class="GtkLabel" id="pin_hint"> |
1959 | + <property name="visible">True</property> |
1960 | + <property name="can-focus">False</property> |
1961 | + <property name="margin-top">6</property> |
1962 | + <property name="margin-bottom">8</property> |
1963 | + <property name="halign">start</property> |
1964 | + <property name="margin-left">62</property> |
1965 | + </object> |
1966 | + </child> |
1967 | + <child> |
1968 | + <object class="GtkRadioButton" id="token_radio"> |
1969 | + <property name="label" translatable="yes">Or add token manually</property> |
1970 | + <property name="visible">True</property> |
1971 | + <property name="can-focus">True</property> |
1972 | + <property name="receives-default">False</property> |
1973 | + <property name="margin-left">30</property> |
1974 | + <property name="margin-top">20</property> |
1975 | + <property name="xalign">0</property> |
1976 | + <property name="group">magic_radio</property> |
1977 | + <signal name="toggled" handler="on_radio_toggled" swapped="no"/> |
1978 | + </object> |
1979 | + </child> |
1980 | + <child> |
1981 | + <object class="GtkBox"> |
1982 | + <property name="visible">True</property> |
1983 | + <property name="can-focus">False</property> |
1984 | + <property name="no-show-all">True</property> |
1985 | + <property name="margin-left">62</property> |
1986 | + <property name="margin-top">12</property> |
1987 | + <property name="margin-bottom">12</property> |
1988 | + <child> |
1989 | + <object class="GtkEntry" id="token_field"> |
1990 | + <property name="visible">True</property> |
1991 | + <property name="sensitive">False</property> |
1992 | + <property name="can-focus">True</property> |
1993 | + <property name="width-chars">35</property> |
1994 | + <property name="placeholder-text" translatable="yes">Token</property> |
1995 | + <property name="valign">center</property> |
1996 | + <signal name="activate" handler="request_token_attach" swapped="no"/> |
1997 | + <signal name="changed" handler="on_token_typing" swapped="no"/> |
1998 | + </object> |
1999 | + </child> |
2000 | + <child> |
2001 | + <object class="GtkFixed"> |
2002 | + <property name="visible">True</property> |
2003 | + <property name="valign">center</property> |
2004 | + <property name="margin">6</property> |
2005 | + <child> |
2006 | + <object class="GtkSpinner" id="token_spinner"> |
2007 | + <property name="visible">True</property> |
2008 | + <property name="valign">center</property> |
2009 | + </object> |
2010 | + </child> |
2011 | + <child> |
2012 | + <object class="GtkImage" id="token_status_icon"> |
2013 | + <property name="visible">False</property> |
2014 | + <property name="valign">center</property> |
2015 | + </object> |
2016 | + </child> |
2017 | + </object> |
2018 | + </child> |
2019 | + <child> |
2020 | + <object class="GtkLabel" id="token_status"> |
2021 | + <property name="visible">True</property> |
2022 | + <property name="valign">center</property> |
2023 | + </object> |
2024 | + </child> |
2025 | + </object> |
2026 | + </child> |
2027 | + <child> |
2028 | + <object class="GtkLabel"> |
2029 | + <property name="visible">True</property> |
2030 | + <property name="label" translatable="yes">From your admin, or from ubuntu.com/pro</property> |
2031 | + <property name="margin-left">62</property> |
2032 | + <property name="halign">start</property> |
2033 | + </object> |
2034 | + </child> |
2035 | + </object> |
2036 | + </child> |
2037 | +</template> |
2038 | +</interface> |
2039 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-offer-page.ui b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-offer-page.ui |
2040 | new file mode 100644 |
2041 | index 0000000..baf941e |
2042 | --- /dev/null |
2043 | +++ b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-offer-page.ui |
2044 | @@ -0,0 +1,165 @@ |
2045 | +<?xml version="1.0" encoding="UTF-8"?> |
2046 | +<interface> |
2047 | + <!-- interface-requires gtk+ 3.0 --> |
2048 | + <template class="GisUbuntuProOfferPage" parent="GtkBin"> |
2049 | + <child> |
2050 | + <object class="GtkBox" id="offer_page"> |
2051 | + <property name="visible">True</property> |
2052 | + <property name="can-focus">False</property> |
2053 | + <property name="no-show-all">True</property> |
2054 | + <property name="orientation">vertical</property> |
2055 | + <child> |
2056 | + <object class="GtkLabel"> |
2057 | + <property name="visible">True</property> |
2058 | + <property name="can-focus">False</property> |
2059 | + <property name="halign">start</property> |
2060 | + <property name="margin-top">3</property> |
2061 | + <property name="margin-bottom">0</property> |
2062 | + <property name="label" translatable="yes"><b>Enable Ubuntu Pro</b></property> |
2063 | + <property name="use-markup">True</property> |
2064 | + <property name="wrap">True</property> |
2065 | + <property name="xalign">0</property> |
2066 | + <attributes> |
2067 | + <attribute name="scale" value="1.4"/> |
2068 | + </attributes> |
2069 | + </object> |
2070 | + </child> |
2071 | + <child> |
2072 | + <object class="GtkSeparator"> |
2073 | + <property name="visible">True</property> |
2074 | + <property name="can-focus">False</property> |
2075 | + <property name="margin-top">10</property> |
2076 | + <property name="margin-bottom">10</property> |
2077 | + </object> |
2078 | + </child> |
2079 | + <child> |
2080 | + <object class="GtkEventBox"> |
2081 | + <property name="visible">True</property> |
2082 | + <property name="can-focus">False</property> |
2083 | + <property name="margin-top">12</property> |
2084 | + <property name="margin-bottom">12</property> |
2085 | + <child> |
2086 | + <object class="GtkBox"> |
2087 | + <property name="visible">True</property> |
2088 | + <property name="can-focus">False</property> |
2089 | + <child> |
2090 | + <object class="GtkImage" id="ubuntu_pro_logo"> |
2091 | + <property name="visible">True</property> |
2092 | + <property name="can-focus">False</property> |
2093 | + <property name="margin-left">30</property> |
2094 | + <property name="margin-right">30</property> |
2095 | + <property name="yalign">0</property> |
2096 | + </object> |
2097 | + </child> |
2098 | + <child> |
2099 | + <object class="GtkLabel"> |
2100 | + <property name="visible">True</property> |
2101 | + <property name="can-focus">True</property> |
2102 | + <property name="margin-right">30</property> |
2103 | + <property name="label" translatable="yes">Upgrade this machine to Ubuntu Pro for security updates on a much wider range of packages, until 2032. Fulfill FedRAMP, FIPS, STIG and HIPAA and other compliance and hardening requirements with certified tooling and crypto-modules. Free up to 5 machines. |
2104 | + |
2105 | +More information on <a href="https://ubuntu.com/pro">ubuntu.com/pro</a>.</property> |
2106 | + <property name="use-markup">True</property> |
2107 | + <property name="wrap">True</property> |
2108 | + <property name="max-width-chars">130</property> |
2109 | + </object> |
2110 | + </child> |
2111 | + </object> |
2112 | + </child> |
2113 | + </object> |
2114 | + </child> |
2115 | + <child> |
2116 | + <object class="GtkLabel"> |
2117 | + <property name="visible">True</property> |
2118 | + <property name="can-focus">False</property> |
2119 | + <property name="margin-top">40</property> |
2120 | + <property name="margin-bottom">6</property> |
2121 | + <property name="margin-left">30</property> |
2122 | + <property name="label" translatable="yes">Enable Ubuntu Pro for this installation or skip this step.</property> |
2123 | + <property name="xalign">0</property> |
2124 | + </object> |
2125 | + </child> |
2126 | + <child> |
2127 | + <object class="GtkBox"> |
2128 | + <property name="visible">True</property> |
2129 | + <property name="can-focus">False</property> |
2130 | + <property name="orientation">vertical</property> |
2131 | + <property name="margin-left">30</property> |
2132 | + <property name="spacing">6</property> |
2133 | + <child> |
2134 | + <object class="GtkBox"> |
2135 | + <property name="visible">True</property> |
2136 | + <property name="can-focus">False</property> |
2137 | + <property name="orientation">horizontal</property> |
2138 | + <child> |
2139 | + <object class="GtkRadioButton" id="enable_pro_select"> |
2140 | + <property name="label" translatable="yes">Enable Ubuntu Pro</property> |
2141 | + <property name="visible">True</property> |
2142 | + <property name="can-focus">True</property> |
2143 | + <property name="receives-default">False</property> |
2144 | + <property name="margin-top">6</property> |
2145 | + <property name="xalign">0</property> |
2146 | + <property name="draw-indicator">True</property> |
2147 | + <property name="group">skip_pro_select</property> |
2148 | + </object> |
2149 | + </child> |
2150 | + <child> |
2151 | + <object class="GtkImage" id="pro_status_image"> |
2152 | + <property name="can-focus">False</property> |
2153 | + <property name="stock">gtk-dialog-warning</property> |
2154 | + <property name="icon_size">2</property> |
2155 | + <property name="margin-left">30</property> |
2156 | + <property name="margin-right">6</property> |
2157 | + <property name="yalign">0.7</property> |
2158 | + </object> |
2159 | + </child> |
2160 | + <child> |
2161 | + <object class="GtkLabel" id="offline_warning"> |
2162 | + <property name="yalign">0.8</property> |
2163 | + <property name="can-focus">False</property> |
2164 | + <property name="label" translatable="yes">An internet connection is required to enable Ubuntu Pro</property> |
2165 | + </object> |
2166 | + </child> |
2167 | + </object> |
2168 | + </child> |
2169 | + <child> |
2170 | + <object class="GtkBox"> |
2171 | + <property name="visible">True</property> |
2172 | + <property name="can-focus">False</property> |
2173 | + <property name="orientation">vertical</property> |
2174 | + <child> |
2175 | + <object class="GtkRadioButton" id="skip_pro_select"> |
2176 | + <property name="label" translatable="yes">Skip for now</property> |
2177 | + <property name="visible">True</property> |
2178 | + <property name="can-focus">True</property> |
2179 | + <property name="receives-default">False</property> |
2180 | + <property name="margin-top">12</property> |
2181 | + <property name="xalign">0</property> |
2182 | + <property name="active">True</property> |
2183 | + <property name="draw-indicator">True</property> |
2184 | + </object> |
2185 | + </child> |
2186 | + <child> |
2187 | + <object class="GtkAlignment"> |
2188 | + <property name="visible">True</property> |
2189 | + <property name="can-focus">False</property> |
2190 | + <property name="left-padding">25</property> |
2191 | + <child> |
2192 | + <object class="GtkLabel"> |
2193 | + <property name="visible">True</property> |
2194 | + <property name="can-focus">False</property> |
2195 | + <property name="label" translatable="yes"><small>You can always enable Ubuntu Pro later via the 'pro attach' command</small></property> |
2196 | + <property name="use-markup">True</property> |
2197 | + <property name="xalign">0</property> |
2198 | + </object> |
2199 | + </child> |
2200 | + </object> |
2201 | + </child> |
2202 | + </object> |
2203 | + </child> |
2204 | + </object> |
2205 | + </child> |
2206 | + </object> |
2207 | + </child> |
2208 | + </template> |
2209 | +</interface> |
2210 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.c b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.c |
2211 | new file mode 100644 |
2212 | index 0000000..adc4ab2 |
2213 | --- /dev/null |
2214 | +++ b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.c |
2215 | @@ -0,0 +1,804 @@ |
2216 | +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ |
2217 | +/* |
2218 | + * Copyright (C) 2022 Canonical Ltd. |
2219 | + * |
2220 | + * This program is free software; you can redistribute it and/or |
2221 | + * modify it under the terms of the GNU General Public License as |
2222 | + * published by the Free Software Foundation; either version 2 of the |
2223 | + * License, or (at your option) any later version. |
2224 | + * |
2225 | + * This program is distributed in the hope that it will be useful, but |
2226 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
2227 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2228 | + * General Public License for more details. |
2229 | + * |
2230 | + * You should have received a copy of the GNU General Public License |
2231 | + * along with this program; if not, see <http://www.gnu.org/licenses/>. |
2232 | + */ |
2233 | + |
2234 | +/* Canonical Ubuntu Pro page {{{1 */ |
2235 | + |
2236 | +#define PAGE_ID "UbuntuPro" |
2237 | +#define CHECK_ICON "/org/gnome/initial-setup/checkmark.svg" |
2238 | +#define FAIL_ICON "/org/gnome/initial-setup/fail.svg" |
2239 | +#define LOGO "/org/gnome/initial-setup/ubuntu-pro.svg" |
2240 | +#define LOGO_DARK "/org/gnome/initial-setup/ubuntu-pro-dark.svg" |
2241 | + |
2242 | +#include "config.h" |
2243 | +#include "gis-ubuntupro-page.h" |
2244 | +#include "ubuntupro-resources.h" |
2245 | +#include "utils.h" |
2246 | + |
2247 | +#include <glib/gi18n.h> |
2248 | +#include <gio/gio.h> |
2249 | +#include <polkit/polkit.h> |
2250 | +#include <json-glib/json-glib.h> |
2251 | +#include <time.h> |
2252 | +#include <pthread.h> |
2253 | + |
2254 | +static gboolean SuccessfullyAttached = FALSE; |
2255 | + |
2256 | +typedef enum { |
2257 | + NONE = 0, |
2258 | + SUCCESS, |
2259 | + FAIL, |
2260 | + EXPIRED, |
2261 | +} status_t; |
2262 | + |
2263 | +struct _GisUbuntuProPagePrivate { |
2264 | + GtkWidget *offer_page; |
2265 | + GtkWidget *attach_page; |
2266 | + GtkWidget *services_page; |
2267 | + GtkWidget *stack; |
2268 | + |
2269 | + enum { |
2270 | + OFFER_PAGE, |
2271 | + ATTACH_PAGE, |
2272 | + SERVICES_PAGE, |
2273 | + } current_page; |
2274 | +}; |
2275 | +typedef struct _GisUbuntuProPagePrivate GisUbuntuProPagePrivate; |
2276 | + |
2277 | +struct _GisUbuntuProOfferPagePrivate { |
2278 | + GtkWidget *ubuntu_pro_logo; |
2279 | + GtkWidget *enable_pro_select; |
2280 | + GtkWidget *skip_pro_select; |
2281 | + GtkWidget *offline_warning; |
2282 | + GtkWidget *pro_status_image; |
2283 | + gint network_cb; |
2284 | +}; |
2285 | +typedef struct _GisUbuntuProOfferPagePrivate GisUbuntuProOfferPagePrivate; |
2286 | + |
2287 | +struct _GisUbuntuProAttachPagePrivate { |
2288 | + GtkWidget *ubuntu_pro_logo; |
2289 | + GtkWidget *pin_label; |
2290 | + GtkWidget *token_field; |
2291 | + GtkWidget *token_status; |
2292 | + GtkWidget *token_spinner; |
2293 | + GtkWidget *pin_spinner; |
2294 | + GtkWidget *token_status_icon; |
2295 | + GtkWidget *pin_hint; |
2296 | + GtkWidget *pin_status; |
2297 | + GtkWidget *pin_status_icon; |
2298 | + GtkWidget *token_radio; |
2299 | + GtkWidget *magic_radio; |
2300 | + /* This being here is a hack that makes changing the 2nd page's button |
2301 | + * from Skip to Next once the machine is attached possible. */ |
2302 | + GisUbuntuProPage *main_page; |
2303 | + |
2304 | + gboolean complete; |
2305 | + gboolean magic_token_polling; |
2306 | + gboolean attaching; |
2307 | + gint64 expired_by; |
2308 | + pthread_t poll_id; |
2309 | + enum active_radio_t { |
2310 | + MAGIC, |
2311 | + TOKEN, |
2312 | + } active_radio; |
2313 | + gchar *contract_token; |
2314 | + gchar *token; |
2315 | +}; |
2316 | +typedef struct _GisUbuntuProAttachPagePrivate GisUbuntuProAttachPagePrivate; |
2317 | + |
2318 | +struct _GisUbuntuProServicesPagePrivate { |
2319 | + GtkWidget *enabled_services; |
2320 | + GtkWidget *enabled_services_header; |
2321 | + GtkWidget *available_services; |
2322 | + GtkWidget *available_services_header; |
2323 | + GtkWidget *contract_name; |
2324 | + GtkWidget *checkmark; |
2325 | +}; |
2326 | +typedef struct _GisUbuntuProServicesPagePrivate GisUbuntuProServicesPagePrivate; |
2327 | + |
2328 | +struct _RestJSONResponse { |
2329 | + gint64 expiresIn; |
2330 | + gchar *token; |
2331 | + gchar *code; |
2332 | + gchar *contract_token; |
2333 | +}; |
2334 | + |
2335 | +typedef struct _RestJSONResponse RestJSONResponse; |
2336 | +static void ua_attach(const gchar *, GisUbuntuProAttachPagePrivate *); |
2337 | +static gboolean magic_parser(gchar*, RestJSONResponse*); |
2338 | +static gboolean gis_ubuntupro_page_apply (GisPage*, GCancellable*); |
2339 | + |
2340 | +G_DEFINE_TYPE_WITH_PRIVATE (GisUbuntuProPage, gis_ubuntupro_page, GIS_TYPE_PAGE); |
2341 | +G_DEFINE_TYPE_WITH_PRIVATE (GisUbuntuProOfferPage, gis_ubuntupro_offer_page, GTK_TYPE_BIN); |
2342 | +G_DEFINE_TYPE_WITH_PRIVATE (GisUbuntuProAttachPage, gis_ubuntupro_attach_page, GTK_TYPE_BIN); |
2343 | +G_DEFINE_TYPE_WITH_PRIVATE (GisUbuntuProServicesPage, gis_ubuntupro_services_page, GTK_TYPE_BIN); |
2344 | + |
2345 | +static void |
2346 | +map_scalable_image(const gchar *path, GtkImage *widget, int x, int y) |
2347 | +{ |
2348 | + g_autoptr(GError) error = NULL; |
2349 | + GdkPixbuf *pixbuf; |
2350 | + pixbuf = gdk_pixbuf_new_from_resource_at_scale (path, x, y, TRUE, &error); |
2351 | + if (error) { |
2352 | + g_warning("Unable to create pixbuf: %s\n", error->message); |
2353 | + } |
2354 | + |
2355 | + if (pixbuf != NULL) { |
2356 | + gtk_image_set_from_pixbuf(widget, pixbuf); |
2357 | + } else { |
2358 | + g_warning("Unable to load pixbuf: %s\n", error->message); |
2359 | + } |
2360 | +} |
2361 | + |
2362 | +/* The user may go back any number of pages during attachment, so we can't |
2363 | + * blindly skip to the services list page. |
2364 | + * Furthermore, after attachment the user can again navigate back to any page |
2365 | + * and then hit the attach page again. |
2366 | + */ |
2367 | +static void |
2368 | +consider_going_to_next_page(GisUbuntuProAttachPagePrivate *priv) |
2369 | +{ |
2370 | + static gboolean never_called = TRUE; |
2371 | + GisUbuntuProPage *page = GIS_UBUNTUPRO_PAGE(priv->main_page); |
2372 | + GisUbuntuProPagePrivate *main_priv = gis_ubuntupro_page_get_instance_private (page); |
2373 | + |
2374 | + if (never_called && main_priv->current_page == ATTACH_PAGE) { |
2375 | + gis_page_set_complete(GIS_PAGE(priv->main_page), TRUE); |
2376 | + gis_ubuntupro_page_apply(GIS_PAGE(priv->main_page), NULL); |
2377 | + } |
2378 | + never_called = FALSE; |
2379 | +} |
2380 | + |
2381 | +static void |
2382 | +update_gui(GisUbuntuProAttachPagePrivate *priv, status_t status) |
2383 | +{ |
2384 | + GtkWidget *label, *icon, *spinner; |
2385 | + gchar *hint = _("Attach machine via your Ubuntu One account"); |
2386 | + gboolean ready_to_attach; |
2387 | + |
2388 | + if (priv->active_radio == MAGIC) { |
2389 | + icon = priv->pin_status_icon; |
2390 | + label = priv->pin_status; |
2391 | + spinner = priv->pin_spinner; |
2392 | + ready_to_attach = SuccessfullyAttached || |
2393 | + (priv->contract_token && !priv->attaching); |
2394 | + } else { |
2395 | + icon = priv->token_status_icon; |
2396 | + label = priv->token_status; |
2397 | + spinner = priv->token_spinner; |
2398 | + ready_to_attach = SuccessfullyAttached || (!priv->attaching && |
2399 | + gtk_entry_get_text_length(GTK_ENTRY(priv->token_field)) > 0); |
2400 | + } |
2401 | + gis_page_set_complete(GIS_PAGE(priv->main_page), ready_to_attach); |
2402 | + |
2403 | + if (priv->attaching) { |
2404 | + gtk_spinner_start (GTK_SPINNER (spinner)); |
2405 | + } else { |
2406 | + gtk_spinner_stop (GTK_SPINNER (spinner)); |
2407 | + } |
2408 | + |
2409 | + gtk_widget_set_sensitive (priv->token_radio, !priv->attaching); |
2410 | + gtk_widget_set_sensitive (priv->magic_radio, !priv->attaching); |
2411 | + gtk_widget_set_sensitive (priv->token_field, !priv->attaching && |
2412 | + priv->active_radio == TOKEN); |
2413 | + |
2414 | + if (SuccessfullyAttached) { |
2415 | + consider_going_to_next_page(priv); |
2416 | + status = SUCCESS; |
2417 | + } |
2418 | + switch (status) { |
2419 | + case SUCCESS: |
2420 | + gtk_label_set_markup(GTK_LABEL(label), g_strconcat( |
2421 | + "<span foreground=\"green\"><b>", _("Valid token"), "</b></span>", NULL |
2422 | + )); |
2423 | + gtk_image_set_from_resource(GTK_IMAGE(icon), CHECK_ICON); |
2424 | + gtk_widget_set_sensitive(GTK_WIDGET(priv->token_field), FALSE); |
2425 | + gtk_widget_set_sensitive(GTK_WIDGET(priv->magic_radio), FALSE); |
2426 | + gtk_widget_set_sensitive(GTK_WIDGET(priv->token_radio), FALSE); |
2427 | + break; |
2428 | + case FAIL: |
2429 | + gtk_label_set_markup(GTK_LABEL(label), g_strconcat( |
2430 | + "<span foreground=\"red\"><b>", _("Invalid token"), "</b></span>", NULL |
2431 | + )); |
2432 | + gtk_image_set_from_resource(GTK_IMAGE(icon), FAIL_ICON); |
2433 | + break; |
2434 | + case EXPIRED: |
2435 | + hint = "Click the button to generate a new code."; |
2436 | + gtk_label_set_markup(GTK_LABEL(label), _("Code expired")); |
2437 | + gtk_image_set_from_resource(GTK_IMAGE(icon), FAIL_ICON); |
2438 | + break; |
2439 | + default: |
2440 | + break; |
2441 | + } |
2442 | + gtk_label_set_text(GTK_LABEL(priv->pin_hint), hint); |
2443 | + gtk_widget_set_visible(GTK_WIDGET(priv->token_status_icon), FALSE); |
2444 | + gtk_widget_set_visible(GTK_WIDGET(priv->token_status), FALSE); |
2445 | + gtk_widget_set_visible(GTK_WIDGET(priv->pin_status_icon), FALSE); |
2446 | + gtk_widget_set_visible(GTK_WIDGET(priv->pin_status), FALSE); |
2447 | + gtk_widget_set_visible(GTK_WIDGET(icon), status); |
2448 | + gtk_widget_set_visible(GTK_WIDGET(label), status); |
2449 | +} |
2450 | + |
2451 | +static void |
2452 | +network_status_changed (GNetworkMonitor *monitor, |
2453 | + gboolean available, |
2454 | + gpointer user_data) |
2455 | +{ |
2456 | + GisUbuntuProOfferPagePrivate *priv = user_data; |
2457 | + |
2458 | + if (!available) { |
2459 | + gtk_widget_set_sensitive (priv->enable_pro_select, FALSE); |
2460 | + gtk_widget_show (GTK_WIDGET (priv->offline_warning)); |
2461 | + gtk_widget_show (GTK_WIDGET (priv->pro_status_image)); |
2462 | + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->skip_pro_select), TRUE); |
2463 | + gtk_image_set_from_icon_name (GTK_IMAGE(priv->pro_status_image), "gtk-dialog-warning", GTK_ICON_SIZE_DND); |
2464 | + } |
2465 | + else { |
2466 | + gtk_widget_set_sensitive (priv->enable_pro_select, TRUE); |
2467 | + gtk_widget_hide (GTK_WIDGET (priv->offline_warning)); |
2468 | + gtk_widget_hide (GTK_WIDGET (priv->pro_status_image)); |
2469 | + } |
2470 | +} |
2471 | + |
2472 | +static void |
2473 | +gis_ubuntupro_page_dispose (GObject *object) |
2474 | +{ |
2475 | + GisUbuntuProPage *page = GIS_UBUNTUPRO_PAGE (object); |
2476 | + GisUbuntuProPagePrivate *priv = gis_ubuntupro_page_get_instance_private (page); |
2477 | + GisUbuntuProOfferPage *offer_page = GIS_UBUNTUPRO_OFFER_PAGE (priv->offer_page); |
2478 | + GisUbuntuProOfferPagePrivate *offer_priv = gis_ubuntupro_offer_page_get_instance_private (offer_page); |
2479 | + |
2480 | + GNetworkMonitor *network_monitor = g_network_monitor_get_default (); |
2481 | + g_signal_handler_disconnect(network_monitor, offer_priv->network_cb); |
2482 | + |
2483 | + G_OBJECT_CLASS (gis_ubuntupro_page_parent_class)->dispose (object); |
2484 | +} |
2485 | + |
2486 | +static void |
2487 | +gis_ubuntupro_page_constructed (GObject *object) |
2488 | +{ |
2489 | + GisUbuntuProPage *page = GIS_UBUNTUPRO_PAGE (object); |
2490 | + GisUbuntuProPagePrivate *priv = gis_ubuntupro_page_get_instance_private (page); |
2491 | + GisUbuntuProOfferPage *offer_page = GIS_UBUNTUPRO_OFFER_PAGE (priv->offer_page); |
2492 | + GisUbuntuProOfferPagePrivate *offer_priv = gis_ubuntupro_offer_page_get_instance_private (offer_page); |
2493 | + GisUbuntuProAttachPage *attach_page = GIS_UBUNTUPRO_ATTACH_PAGE (priv->attach_page); |
2494 | + GisUbuntuProAttachPagePrivate *attach_priv = gis_ubuntupro_attach_page_get_instance_private (attach_page); |
2495 | + GisUbuntuProServicesPage *services_page = GIS_UBUNTUPRO_SERVICES_PAGE(priv->services_page); |
2496 | + GisUbuntuProServicesPagePrivate *services_priv = gis_ubuntupro_services_page_get_instance_private (services_page); |
2497 | + |
2498 | + gchar *logo = is_dark_theme(GTK_WIDGET(page)) ? LOGO_DARK: LOGO; |
2499 | + map_scalable_image(logo, GTK_IMAGE(attach_priv->ubuntu_pro_logo), -1, 66); |
2500 | + map_scalable_image(logo, GTK_IMAGE(offer_priv->ubuntu_pro_logo), -1, 66); |
2501 | + map_scalable_image(CHECK_ICON, GTK_IMAGE(services_priv->checkmark), 30, -1); |
2502 | + |
2503 | + G_OBJECT_CLASS (gis_ubuntupro_page_parent_class)->constructed (object); |
2504 | + |
2505 | + GNetworkMonitor *network_monitor = g_network_monitor_get_default (); |
2506 | + offer_priv->network_cb = g_signal_connect (network_monitor, "network-changed", |
2507 | + G_CALLBACK (network_status_changed), priv); |
2508 | + |
2509 | + if (!g_network_monitor_get_network_available (network_monitor)) { |
2510 | + gtk_widget_set_sensitive (offer_priv->enable_pro_select, FALSE); |
2511 | + gtk_widget_show (GTK_WIDGET (offer_priv->offline_warning)); |
2512 | + gtk_widget_show (GTK_WIDGET (offer_priv->pro_status_image)); |
2513 | + } |
2514 | + |
2515 | + /* Initializate priv values */ |
2516 | + attach_priv->magic_token_polling = FALSE; |
2517 | + attach_priv->active_radio = MAGIC; |
2518 | + attach_priv->expired_by = 0; |
2519 | + attach_priv->contract_token = NULL; |
2520 | + attach_priv->main_page = page; |
2521 | + priv->current_page = OFFER_PAGE; |
2522 | + |
2523 | + gis_page_set_skippable (GIS_PAGE (page), FALSE); |
2524 | + gis_page_set_complete (GIS_PAGE (page), TRUE); |
2525 | + gtk_widget_show (GTK_WIDGET (page)); |
2526 | +} |
2527 | + |
2528 | +static void |
2529 | +gis_ubuntupro_page_locale_changed (GisPage *page) |
2530 | +{ |
2531 | + gis_page_set_title (GIS_PAGE (page), _("Ubuntu Pro")); |
2532 | +} |
2533 | + |
2534 | +static gboolean |
2535 | +poll_token_attach (GisUbuntuProAttachPagePrivate *priv) |
2536 | +{ |
2537 | + gchar *std_out, *std_err, *cmd; |
2538 | + RestJSONResponse resp; /* relevant response fields */ |
2539 | + g_autoptr(GError) error = NULL; |
2540 | + |
2541 | + cmd = g_strconcat("/bin/ua api u.pro.attach.magic.wait.v1 --args magic_token=", priv->token, NULL); |
2542 | + if (!g_spawn_command_line_sync(cmd, &std_out, &std_err, NULL, &error)) { |
2543 | + g_warning ("Failed to request magic token: %s", error->message); |
2544 | + } |
2545 | + else if (!magic_parser(std_out, &resp)) { |
2546 | + g_warning("Couldn't parse response."); |
2547 | + } |
2548 | + else if (resp.contract_token != NULL) { |
2549 | + priv->contract_token = g_strdup(resp.contract_token); |
2550 | + return TRUE; |
2551 | + } |
2552 | + return FALSE; |
2553 | +} |
2554 | + |
2555 | +static void* |
2556 | +poll_magic_token (void *data) |
2557 | +{ |
2558 | + GisUbuntuProAttachPagePrivate *priv = gis_ubuntupro_attach_page_get_instance_private (data); |
2559 | + status_t status; |
2560 | + |
2561 | + if (priv->active_radio != MAGIC) { |
2562 | + pthread_exit(NULL); |
2563 | + } |
2564 | + priv->magic_token_polling = TRUE; |
2565 | + |
2566 | + if (time(0) > priv->expired_by) { |
2567 | + status = EXPIRED; |
2568 | + update_gui(priv, status); |
2569 | + priv->magic_token_polling = FALSE; |
2570 | + } |
2571 | + gboolean token_received = poll_token_attach(priv); |
2572 | + if (token_received) { |
2573 | + priv->magic_token_polling = FALSE; |
2574 | + status = SUCCESS; |
2575 | + update_gui(priv, status); |
2576 | + } |
2577 | + pthread_exit(NULL); |
2578 | +} |
2579 | + |
2580 | +static gboolean |
2581 | +magic_parser(gchar *ptr, /* pointer to actual response */ |
2582 | + RestJSONResponse *resp) /* relevant response fields */ |
2583 | +{ |
2584 | + g_autoptr(JsonParser) parser = json_parser_new(); |
2585 | + JsonNode *root; |
2586 | + g_autoptr(GError) error = NULL; |
2587 | + |
2588 | + json_parser_load_from_data(parser, ptr, -1, &error); |
2589 | + if (error) { |
2590 | + g_warning("Couldn't parse magic token JSON; %s\n", error->message); |
2591 | + g_print("%s\n", ptr); |
2592 | + return FALSE; |
2593 | + } |
2594 | + root = json_parser_get_root(parser); |
2595 | + if (!JSON_NODE_HOLDS_OBJECT(root)) { |
2596 | + g_warning("Invalid magic token JSON\n"); |
2597 | + return FALSE; |
2598 | + } |
2599 | + |
2600 | + JsonObject *data, *attributes; |
2601 | + JsonObject *response = json_node_get_object(root); |
2602 | + data = json_object_get_object_member(response, "data"); |
2603 | + attributes = json_object_get_object_member(data, "attributes"); |
2604 | + |
2605 | + resp->expiresIn = json_object_has_member(attributes, "expires_in") ? |
2606 | + json_object_get_int_member(attributes, "expires_in") : |
2607 | + 0; |
2608 | + resp->token = json_object_has_member(attributes, "token") ? |
2609 | + g_strdup(json_object_get_string_member(attributes, "token")) : |
2610 | + NULL; |
2611 | + resp->code = json_object_has_member(attributes, "user_code") ? |
2612 | + g_strdup(json_object_get_string_member(attributes, "user_code")) : |
2613 | + NULL; |
2614 | + resp->contract_token = json_object_has_member(attributes, "contract_token") ? |
2615 | + g_strdup(json_object_get_string_member(attributes, "contract_token")) : |
2616 | + NULL; |
2617 | + |
2618 | + return TRUE; |
2619 | +} |
2620 | + |
2621 | +static void |
2622 | +display_ua_services(GisUbuntuProServicesPagePrivate *priv) |
2623 | +{ |
2624 | + g_autoptr(JsonParser) parser = json_parser_new(); |
2625 | + JsonNode *root_node; |
2626 | + JsonObject *root, *services, *contract; |
2627 | + JsonArray *services_array; |
2628 | + g_autoptr(GError) error = NULL; |
2629 | + guint i, n_services; |
2630 | + const char *status, *description, *available, *contract_name; |
2631 | + gsize len; |
2632 | + g_autofree gchar *str, *enabled_str, *available_str; |
2633 | + |
2634 | + if (!parse_ua_status(&str, &len)) { |
2635 | + return; |
2636 | + } |
2637 | + available_str = (gchar *)g_malloc0(len); |
2638 | + enabled_str = (gchar *)g_malloc0(len); |
2639 | + |
2640 | + json_parser_load_from_data(parser, str, strlen(str), &error); |
2641 | + if (error) { |
2642 | + g_warning("Couldn't parse magic token JSON; %s\n", error->message); |
2643 | + } |
2644 | + root_node = json_parser_get_root(parser); |
2645 | + if (!JSON_NODE_HOLDS_OBJECT(root_node)) { |
2646 | + g_warning("Invalid magic token JSON\n"); |
2647 | + } |
2648 | + |
2649 | + root = json_node_get_object(root_node); |
2650 | + |
2651 | + contract = json_object_get_object_member(root, "contract"); |
2652 | + contract_name = json_object_get_string_member(contract, "name"); |
2653 | + gtk_label_set_text(GTK_LABEL(priv->contract_name), contract_name); |
2654 | + |
2655 | + services_array = json_object_get_array_member(root, "services"); |
2656 | + n_services = json_array_get_length(services_array); |
2657 | + |
2658 | + /* Get services description, status and availability */ |
2659 | + for (i = 0; i < n_services; i++) { |
2660 | + services = json_array_get_object_element(services_array, i); |
2661 | + if ( |
2662 | + json_object_has_member(services, "description") && |
2663 | + json_object_has_member(services, "status") && |
2664 | + json_object_has_member(services, "available") |
2665 | + ) { |
2666 | + description = json_object_get_string_member(services, "description"); |
2667 | + status = json_object_get_string_member(services, "status"); |
2668 | + available = json_object_get_string_member(services, "available"); |
2669 | + if (strcmp(status, "enabled") == 0) { |
2670 | + itemize(enabled_str, description, len); |
2671 | + } else if (strcmp(available, "yes") == 0) { |
2672 | + itemize(available_str, description, len); |
2673 | + } |
2674 | + } |
2675 | + } |
2676 | + |
2677 | + /* Display enabled and disabled but available services */ |
2678 | + if (enabled_str == NULL) { |
2679 | + gtk_widget_destroy(GTK_WIDGET(priv->enabled_services_header)); |
2680 | + } else { |
2681 | + gtk_label_set_text(GTK_LABEL(priv->enabled_services), enabled_str); |
2682 | + } |
2683 | + if (available_str == NULL) { |
2684 | + gtk_widget_destroy(GTK_WIDGET(priv->available_services_header)); |
2685 | + } else { |
2686 | + gtk_label_set_text(GTK_LABEL(priv->available_services), available_str); |
2687 | + } |
2688 | +} |
2689 | + |
2690 | +static void |
2691 | +request_magic_attach (GisUbuntuProAttachPage *page) |
2692 | +{ |
2693 | + GisUbuntuProAttachPagePrivate *priv = gis_ubuntupro_attach_page_get_instance_private (page); |
2694 | + gchar *std_out, *std_err; |
2695 | + g_autoptr(GError) error = NULL; |
2696 | + int rc; |
2697 | + |
2698 | + if (priv->magic_token_polling) { |
2699 | + return; |
2700 | + } |
2701 | + |
2702 | + if (!g_spawn_command_line_sync("/bin/ua api u.pro.attach.magic.initiate.v1", |
2703 | + &std_out, &std_err, NULL, &error)) { |
2704 | + g_warning ("Failed to request magic token: %s", error->message); |
2705 | + return; |
2706 | + } |
2707 | + |
2708 | + RestJSONResponse resp; |
2709 | + if (!magic_parser(std_out, &resp)) { |
2710 | + g_print("%s\n",std_out); |
2711 | + g_warning("Couldn't parse response.\n"); |
2712 | + return; |
2713 | + } |
2714 | + gtk_label_set_text (GTK_LABEL (priv->pin_label), resp.code); |
2715 | + priv->expired_by = resp.expiresIn + time(0); |
2716 | + priv->token = g_strdup(resp.token); |
2717 | + priv->magic_token_polling = TRUE; |
2718 | + rc = pthread_create(&priv->poll_id, NULL, poll_magic_token, (void *)page); |
2719 | + if (rc) { |
2720 | + g_warning ("Couldn't create PIN polling thread"); |
2721 | + return; |
2722 | + } |
2723 | + update_gui(priv, 0); |
2724 | + g_free(resp.token); |
2725 | + g_free(resp.code); |
2726 | +} |
2727 | + |
2728 | +static void |
2729 | +on_ua_attach_requested (GObject *source, |
2730 | + GAsyncResult *result, |
2731 | + gpointer user_data) |
2732 | +{ |
2733 | + GisUbuntuProAttachPagePrivate *priv = user_data; |
2734 | + g_autoptr(GError) error = NULL; |
2735 | + g_autoptr(GVariant) retval = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error); |
2736 | + status_t status; |
2737 | + |
2738 | + if (retval == NULL) { |
2739 | + g_warning ("Failed to attach token: %s", error->message); |
2740 | + status = FAIL; |
2741 | + } else { |
2742 | + SuccessfullyAttached = TRUE; |
2743 | + status = SUCCESS; |
2744 | + pthread_cancel(priv->poll_id); |
2745 | + gis_page_set_complete (GIS_PAGE(priv->main_page), TRUE); |
2746 | + g_free(priv->contract_token); |
2747 | + g_free(priv->token); |
2748 | + } |
2749 | + priv->attaching = FALSE; |
2750 | + update_gui(priv, status); |
2751 | +} |
2752 | + |
2753 | +static void |
2754 | +ua_attach(const gchar *token, GisUbuntuProAttachPagePrivate *priv) |
2755 | +{ |
2756 | + GDBusConnection *bus; |
2757 | + g_autoptr(GError) error = NULL; |
2758 | + status_t status = NONE; |
2759 | + |
2760 | + if (priv->attaching) { |
2761 | + return; |
2762 | + } |
2763 | + |
2764 | + bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); |
2765 | + if (bus == NULL) { |
2766 | + g_warning("Failed to get system bus: %s", error->message); |
2767 | + } else { |
2768 | + priv->attaching = TRUE; |
2769 | + update_gui(priv, status); |
2770 | + |
2771 | + g_dbus_connection_call(bus, |
2772 | + "com.canonical.UbuntuAdvantage", |
2773 | + "/com/canonical/UbuntuAdvantage/Manager", |
2774 | + "com.canonical.UbuntuAdvantage.Manager", |
2775 | + "Attach", |
2776 | + g_variant_new("(s)", token), |
2777 | + G_VARIANT_TYPE("()"), |
2778 | + G_DBUS_CALL_FLAGS_NONE, |
2779 | + 543210, /* I have observed that -1, the default timeout, is not enough. */ |
2780 | + NULL, |
2781 | + on_ua_attach_requested, |
2782 | + priv); |
2783 | + } |
2784 | +} |
2785 | + |
2786 | +void |
2787 | +on_token_typing (GtkButton *button, GisUbuntuProAttachPage *page) |
2788 | +{ |
2789 | + GisUbuntuProAttachPagePrivate *priv = gis_ubuntupro_attach_page_get_instance_private (page); |
2790 | + |
2791 | + gis_page_set_complete ( |
2792 | + GIS_PAGE(priv->main_page), |
2793 | + gtk_entry_get_text_length(GTK_ENTRY(priv->token_field)) > 0 |
2794 | + ); |
2795 | +} |
2796 | + |
2797 | +void |
2798 | +request_token_attach (GtkButton *button, GisUbuntuProAttachPage *page) |
2799 | +{ |
2800 | + GisUbuntuProAttachPagePrivate *priv = gis_ubuntupro_attach_page_get_instance_private (page); |
2801 | + |
2802 | + const gchar *token = gtk_entry_get_text(GTK_ENTRY(priv->token_field)); |
2803 | + ua_attach(token, priv); |
2804 | + gtk_entry_set_text(GTK_ENTRY(priv->token_field), ""); |
2805 | +} |
2806 | + |
2807 | +void |
2808 | +on_magic_clicked (GtkButton *button, GisUbuntuProAttachPage *page) |
2809 | +{ |
2810 | + GisUbuntuProAttachPagePrivate *priv = gis_ubuntupro_attach_page_get_instance_private (page); |
2811 | + priv->active_radio = MAGIC; |
2812 | + |
2813 | + request_magic_attach(page); |
2814 | +} |
2815 | + |
2816 | +void |
2817 | +on_radio_toggled (GtkButton *button, GisUbuntuProAttachPage *page) |
2818 | +{ |
2819 | + GisUbuntuProAttachPagePrivate *priv = gis_ubuntupro_attach_page_get_instance_private (page); |
2820 | + status_t status = NONE; |
2821 | + |
2822 | + priv->active_radio = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->token_radio)) ? TOKEN : MAGIC; |
2823 | + update_gui(priv, status); |
2824 | +} |
2825 | + |
2826 | +/* Callback for the Previous button */ |
2827 | +static gboolean |
2828 | +gis_ubuntupro_page_go_back (GisPage *gis_page) |
2829 | +{ |
2830 | + GisUbuntuProPage *page = GIS_UBUNTUPRO_PAGE (gis_page); |
2831 | + GisUbuntuProPagePrivate *priv = gis_ubuntupro_page_get_instance_private (page); |
2832 | + GisUbuntuProOfferPage *offer_page = GIS_UBUNTUPRO_OFFER_PAGE (priv->offer_page); |
2833 | + GisUbuntuProAttachPage *attach_page = GIS_UBUNTUPRO_ATTACH_PAGE (priv->attach_page); |
2834 | + |
2835 | + switch (priv->current_page) { |
2836 | + case OFFER_PAGE: |
2837 | + return FALSE; |
2838 | + case ATTACH_PAGE: |
2839 | + gis_page_set_complete (gis_page, TRUE); |
2840 | + gtk_stack_set_visible_child (GTK_STACK (priv->stack), GTK_WIDGET(offer_page)); |
2841 | + priv->current_page = OFFER_PAGE; |
2842 | + break; |
2843 | + case SERVICES_PAGE: |
2844 | + gtk_stack_set_visible_child (GTK_STACK (priv->stack), GTK_WIDGET(attach_page)); |
2845 | + priv->current_page = ATTACH_PAGE; |
2846 | + break; |
2847 | + } |
2848 | + return TRUE; |
2849 | +} |
2850 | + |
2851 | +/* Callback for the Next button */ |
2852 | +static gboolean |
2853 | +gis_ubuntupro_page_apply (GisPage *gis_page, |
2854 | + GCancellable *cancellable) |
2855 | +{ |
2856 | + GisUbuntuProPage *page = GIS_UBUNTUPRO_PAGE (gis_page); |
2857 | + GisUbuntuProPagePrivate *priv = gis_ubuntupro_page_get_instance_private (page); |
2858 | + GisUbuntuProOfferPage *offer_page = GIS_UBUNTUPRO_OFFER_PAGE (priv->offer_page); |
2859 | + GisUbuntuProOfferPagePrivate *offer_priv = gis_ubuntupro_offer_page_get_instance_private (offer_page); |
2860 | + GisUbuntuProAttachPage *attach_page = GIS_UBUNTUPRO_ATTACH_PAGE (priv->attach_page); |
2861 | + GisUbuntuProAttachPagePrivate *attach_priv = gis_ubuntupro_attach_page_get_instance_private (attach_page); |
2862 | + switch (priv->current_page) { |
2863 | + case OFFER_PAGE: |
2864 | + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (offer_priv->skip_pro_select))) { |
2865 | + return FALSE; |
2866 | + } |
2867 | + /* Request magic token already if didn't yet and advance to next local page */ |
2868 | + if (!SuccessfullyAttached && !attach_priv->attaching) { |
2869 | + request_magic_attach(attach_page); |
2870 | + } |
2871 | + gis_page_apply_complete (GIS_PAGE (page), FALSE); |
2872 | + update_gui(attach_priv, 0); |
2873 | + gtk_stack_set_visible_child (GTK_STACK (priv->stack), GTK_WIDGET(attach_page)); |
2874 | + priv->current_page = ATTACH_PAGE; |
2875 | + break; |
2876 | + case ATTACH_PAGE: |
2877 | + if (SuccessfullyAttached) { |
2878 | + GisUbuntuProServicesPage *services_page = GIS_UBUNTUPRO_SERVICES_PAGE(priv->services_page); |
2879 | + display_ua_services(gis_ubuntupro_services_page_get_instance_private (services_page)); |
2880 | + gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->services_page); |
2881 | + gis_page_apply_complete (GIS_PAGE (page), FALSE); |
2882 | + } else { |
2883 | + if (attach_priv->active_radio == MAGIC) { |
2884 | + ua_attach(attach_priv->contract_token, attach_priv); |
2885 | + } else { |
2886 | + request_token_attach(NULL, attach_page); |
2887 | + } |
2888 | + gis_page_apply_complete (GIS_PAGE (page), FALSE); |
2889 | + return FALSE; |
2890 | + } |
2891 | + priv->current_page = SERVICES_PAGE; |
2892 | + break; |
2893 | + case SERVICES_PAGE: |
2894 | + return FALSE; |
2895 | + } |
2896 | + return TRUE; |
2897 | +} |
2898 | + |
2899 | +static void |
2900 | +gis_ubuntupro_page_class_init (GisUbuntuProPageClass *klass) |
2901 | +{ |
2902 | + GisPageClass *page_class = GIS_PAGE_CLASS (klass); |
2903 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
2904 | + |
2905 | + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-ubuntupro-page.ui"); |
2906 | + |
2907 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProPage, offer_page); |
2908 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProPage, attach_page); |
2909 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProPage, services_page); |
2910 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProPage, stack); |
2911 | + gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), request_token_attach); |
2912 | + gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), request_magic_attach); |
2913 | + gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), on_radio_toggled); |
2914 | + gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), on_magic_clicked); |
2915 | + |
2916 | + page_class->page_id = PAGE_ID; |
2917 | + page_class->locale_changed = gis_ubuntupro_page_locale_changed; |
2918 | + page_class->apply = gis_ubuntupro_page_apply; |
2919 | + page_class->go_back = gis_ubuntupro_page_go_back; |
2920 | + object_class->constructed = gis_ubuntupro_page_constructed; |
2921 | + object_class->dispose = gis_ubuntupro_page_dispose; |
2922 | +} |
2923 | +static void |
2924 | +gis_ubuntupro_offer_page_class_init (GisUbuntuProOfferPageClass *klass) |
2925 | +{ |
2926 | + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-ubuntupro-offer-page.ui"); |
2927 | + |
2928 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProOfferPage, ubuntu_pro_logo); |
2929 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProOfferPage, enable_pro_select); |
2930 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProOfferPage, skip_pro_select); |
2931 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProOfferPage, offline_warning); |
2932 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProOfferPage, pro_status_image); |
2933 | +} |
2934 | + |
2935 | +static void |
2936 | +gis_ubuntupro_attach_page_class_init (GisUbuntuProAttachPageClass *klass) |
2937 | +{ |
2938 | + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-ubuntupro-attach-page.ui"); |
2939 | + |
2940 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, ubuntu_pro_logo); |
2941 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, pin_label); |
2942 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, token_field); |
2943 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, token_status); |
2944 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, token_spinner); |
2945 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, token_status_icon); |
2946 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, pin_status); |
2947 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, pin_spinner); |
2948 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, pin_status_icon); |
2949 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, pin_hint); |
2950 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, token_radio); |
2951 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProAttachPage, magic_radio); |
2952 | +} |
2953 | +static void |
2954 | +gis_ubuntupro_services_page_class_init (GisUbuntuProServicesPageClass *klass) |
2955 | +{ |
2956 | + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-ubuntupro-services-page.ui"); |
2957 | + |
2958 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProServicesPage, enabled_services); |
2959 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProServicesPage, enabled_services_header); |
2960 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProServicesPage, available_services); |
2961 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProServicesPage, available_services_header); |
2962 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProServicesPage, contract_name); |
2963 | + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisUbuntuProServicesPage, checkmark); |
2964 | +} |
2965 | + |
2966 | +static void |
2967 | +gis_ubuntupro_page_init (GisUbuntuProPage *page) |
2968 | +{ |
2969 | + g_resources_register (ubuntupro_get_resource ()); |
2970 | + |
2971 | + /* Magic that makes stuff compile */ |
2972 | + gis_ubuntupro_offer_page_get_type (); |
2973 | + gis_ubuntupro_attach_page_get_type (); |
2974 | + gis_ubuntupro_services_page_get_type (); |
2975 | + |
2976 | + gtk_widget_init_template (GTK_WIDGET (page)); |
2977 | +} |
2978 | +static void |
2979 | +gis_ubuntupro_offer_page_init (GisUbuntuProOfferPage *page) |
2980 | +{ |
2981 | + g_resources_register (ubuntupro_get_resource ()); |
2982 | + |
2983 | + gtk_widget_init_template (GTK_WIDGET (page)); |
2984 | +} |
2985 | +static void |
2986 | +gis_ubuntupro_attach_page_init (GisUbuntuProAttachPage *page) |
2987 | +{ |
2988 | + g_resources_register (ubuntupro_get_resource ()); |
2989 | + |
2990 | + gtk_widget_init_template (GTK_WIDGET (page)); |
2991 | +} |
2992 | +static void |
2993 | +gis_ubuntupro_services_page_init (GisUbuntuProServicesPage *page) |
2994 | +{ |
2995 | + g_resources_register (ubuntupro_get_resource ()); |
2996 | + |
2997 | + gtk_widget_init_template (GTK_WIDGET (page)); |
2998 | +} |
2999 | + |
3000 | +GisPage * |
3001 | +gis_prepare_ubuntu_pro_page (GisDriver *driver) |
3002 | +{ |
3003 | + gboolean attached; |
3004 | + if (!get_ubuntu_advantage_attached (&attached)) { |
3005 | + g_warning("Couldn't fetch the Ubuntu Pro status.\n"); |
3006 | + return NULL; |
3007 | + } |
3008 | + if (attached) { |
3009 | + g_warning("Ubuntu Pro is already attached. Skipping Ubuntu Pro pages.\n"); |
3010 | + return NULL; |
3011 | + } |
3012 | + |
3013 | + if (!is_ubuntupro_supported ()) |
3014 | + return NULL; |
3015 | + |
3016 | + return g_object_new (GIS_TYPE_UBUNTUPRO_PAGE, |
3017 | + "driver", driver, |
3018 | + NULL); |
3019 | +} |
3020 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.h b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.h |
3021 | new file mode 100644 |
3022 | index 0000000..50676c2 |
3023 | --- /dev/null |
3024 | +++ b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.h |
3025 | @@ -0,0 +1,110 @@ |
3026 | +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ |
3027 | +/* |
3028 | + * Copyright (C) 2018 Canonical Ltd. |
3029 | + * |
3030 | + * This program is free software; you can redistribute it and/or |
3031 | + * modify it under the terms of the GNU General Public License as |
3032 | + * published by the Free Software Foundation; either version 2 of the |
3033 | + * License, or (at your option) any later version. |
3034 | + * |
3035 | + * This program is distributed in the hope that it will be useful, but |
3036 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
3037 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3038 | + * General Public License for more details. |
3039 | + * |
3040 | + * You should have received a copy of the GNU General Public License |
3041 | + * along with this program; if not, see <http://www.gnu.org/licenses/>. |
3042 | + */ |
3043 | + |
3044 | +#ifndef __GIS_UBUNTUPRO_PAGE_H__ |
3045 | +#define __GIS_UBUNTUPRO_PAGE_H__ |
3046 | + |
3047 | +#include "gnome-initial-setup.h" |
3048 | + |
3049 | +G_BEGIN_DECLS |
3050 | + |
3051 | +#define GIS_TYPE_UBUNTUPRO_PAGE (gis_ubuntupro_page_get_type ()) |
3052 | +#define GIS_TYPE_UBUNTUPRO_OFFER_PAGE (gis_ubuntupro_offer_page_get_type ()) |
3053 | +#define GIS_TYPE_UBUNTUPRO_ATTACH_PAGE (gis_ubuntupro_attach_page_get_type ()) |
3054 | +#define GIS_TYPE_UBUNTUPRO_SERVICES_PAGE (gis_ubuntupro_services_page_get_type ()) |
3055 | + |
3056 | +#define GIS_UBUNTUPRO_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_UBUNTUPRO_PAGE, GisUbuntuProPage)) |
3057 | +#define GIS_UBUNTUPRO_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_UBUNTUPRO_PAGE, GisUbuntuProPageClass)) |
3058 | +#define GIS_UBUNTUPRO_OFFER_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_UBUNTUPRO_OFFER_PAGE, GisUbuntuProOfferPage)) |
3059 | +#define GIS_UBUNTUPRO_OFFER_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_UBUNTUPRO_OFFER_PAGE, GisUbuntuProOfferPageClass)) |
3060 | +#define GIS_UBUNTUPRO_ATTACH_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_UBUNTUPRO_ATTACH_PAGE, GisUbuntuProAttachPage)) |
3061 | +#define GIS_UBUNTUPRO_ATTACH_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_UBUNTUPRO_ATTACH_PAGE, GisUbuntuProAttachPageClass)) |
3062 | +#define GIS_UBUNTUPRO_SERVICES_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_UBUNTUPRO_SERVICES_PAGE, GisUbuntuProServicesPage)) |
3063 | +#define GIS_UBUNTUPRO_SERVICES_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_UBUNTUPRO_SERVICES_PAGE, GisUbuntuProServicesPageClass)) |
3064 | + |
3065 | +#define GIS_IS_UBUNTUPRO_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_UBUNTUPRO_PAGE)) |
3066 | +#define GIS_IS_UBUNTUPRO_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_UBUNTUPRO_PAGE)) |
3067 | +#define GIS_IS_UBUNTUPRO_OFFER_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_UBUNTUPRO_OFFER_PAGE)) |
3068 | +#define GIS_IS_UBUNTUPRO_OFFER_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_UBUNTUPRO_OFFER_PAGE)) |
3069 | +#define GIS_IS_UBUNTUPRO_ATTACH_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_UBUNTUPRO_ATTACH_PAGE)) |
3070 | +#define GIS_IS_UBUNTUPRO_ATTACH_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_UBUNTUPRO_ATTACH_PAGE)) |
3071 | +#define GIS_IS_UBUNTUPRO_SERVICES_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_UBUNTUPRO_SERVICES_PAGE)) |
3072 | +#define GIS_IS_UBUNTUPRO_SERVICES_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_UBUNTUPRO_SERVICES_PAGE)) |
3073 | + |
3074 | +#define GIS_UBUNTUPRO_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_UBUNTUPRO_PAGE, GisUbuntuProPageClass)) |
3075 | +#define GIS_UBUNTUPRO_OFFER_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_UBUNTUPRO_OFFER_PAGE, GisUbuntuProOfferPageClass)) |
3076 | +#define GIS_UBUNTUPRO_ATTACH_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_UBUNTUPRO_ATTACH_PAGE, GisUbuntuProAttachPageClass)) |
3077 | +#define GIS_UBUNTUPRO_SERVICES_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_UBUNTUPRO_SERVICES_PAGE, GisUbuntuProServicesPageClass)) |
3078 | + |
3079 | +typedef struct _GisUbuntuProPage GisUbuntuProPage; |
3080 | +typedef struct _GisUbuntuProPageClass GisUbuntuProPageClass; |
3081 | +typedef struct _GisUbuntuProOfferPage GisUbuntuProOfferPage; |
3082 | +typedef struct _GisUbuntuProOfferPageClass GisUbuntuProOfferPageClass; |
3083 | +typedef struct _GisUbuntuProAttachPage GisUbuntuProAttachPage; |
3084 | +typedef struct _GisUbuntuProAttachPageClass GisUbuntuProAttachPageClass; |
3085 | +typedef struct _GisUbuntuProServicesPage GisUbuntuProServicesPage; |
3086 | +typedef struct _GisUbuntuProServicesPageClass GisUbuntuProServicesPageClass; |
3087 | + |
3088 | +struct _GisUbuntuProPage |
3089 | +{ |
3090 | + GisPage parent; |
3091 | +}; |
3092 | +struct _GisUbuntuProPageClass |
3093 | +{ |
3094 | + GisPageClass parent_class; |
3095 | +}; |
3096 | + |
3097 | +struct _GisUbuntuProOfferPage |
3098 | +{ |
3099 | + GtkBin parent; |
3100 | +}; |
3101 | +struct _GisUbuntuProOfferPageClass |
3102 | +{ |
3103 | + GtkBinClass parent_class; |
3104 | +}; |
3105 | + |
3106 | +struct _GisUbuntuProAttachPage |
3107 | +{ |
3108 | + GtkBin parent; |
3109 | +}; |
3110 | +struct _GisUbuntuProAttachPageClass |
3111 | +{ |
3112 | + GtkBinClass parent_class; |
3113 | +}; |
3114 | + |
3115 | +struct _GisUbuntuProServicesPage |
3116 | +{ |
3117 | + GtkBin parent; |
3118 | +}; |
3119 | + |
3120 | +struct _GisUbuntuProServicesPageClass |
3121 | +{ |
3122 | + GtkBinClass parent_class; |
3123 | +}; |
3124 | + |
3125 | +GType gis_ubuntupro_page_get_type (void); |
3126 | +GType gis_ubuntupro_offer_page_get_type (void); |
3127 | +GType gis_ubuntupro_attach_page_get_type (void); |
3128 | +GType gis_ubuntupro_services_page_get_type (void); |
3129 | + |
3130 | +GisPage *gis_prepare_ubuntu_pro_page (GisDriver *driver); |
3131 | + |
3132 | + |
3133 | +G_END_DECLS |
3134 | + |
3135 | +#endif /* __GIS_UBUNTUPRO_PAGE_H__ */ |
3136 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.ui b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.ui |
3137 | new file mode 100644 |
3138 | index 0000000..883c92c |
3139 | --- /dev/null |
3140 | +++ b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.ui |
3141 | @@ -0,0 +1,39 @@ |
3142 | +<?xml version="1.0" encoding="UTF-8"?> |
3143 | +<interface> |
3144 | + <!-- interface-requires gtk+ 3.0 --> |
3145 | + <template class="GisUbuntuProPage" parent="GisPage"> |
3146 | + <child> |
3147 | + <object class="GtkBox" id="stepUbuntuPro"> |
3148 | + <property name="visible">True</property> |
3149 | + <property name="can-focus">False</property> |
3150 | + <child> |
3151 | + <object class="GtkStack" id="stack"> |
3152 | + <property name="visible">True</property> |
3153 | + <property name="valign">start</property> |
3154 | + <property name="vexpand">True</property> |
3155 | + <child> |
3156 | + <object class="GisUbuntuProOfferPage" id="offer_page"> |
3157 | + <property name="visible">True</property> |
3158 | + </object> |
3159 | + </child> |
3160 | + <child> |
3161 | + <object class="GisUbuntuProAttachPage" id="attach_page"> |
3162 | + <property name="visible">True</property> |
3163 | + </object> |
3164 | + </child> |
3165 | + <child> |
3166 | + <object class="GisUbuntuProServicesPage" id="services_page"> |
3167 | + <property name="visible">True</property> |
3168 | + </object> |
3169 | + </child> |
3170 | + </object> |
3171 | + <packing> |
3172 | + <property name="expand">False</property> |
3173 | + <property name="fill">True</property> |
3174 | + <property name="position">0</property> |
3175 | + </packing> |
3176 | + </child> |
3177 | + </object> |
3178 | + </child> |
3179 | + </template> |
3180 | +</interface> |
3181 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-services-page.ui b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-services-page.ui |
3182 | new file mode 100644 |
3183 | index 0000000..8fcbe2a |
3184 | --- /dev/null |
3185 | +++ b/gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-services-page.ui |
3186 | @@ -0,0 +1,124 @@ |
3187 | +<?xml version="1.0" encoding="UTF-8"?> |
3188 | +<interface> |
3189 | + <!-- interface-requires gtk+ 3.0 --> |
3190 | + <template class="GisUbuntuProServicesPage" parent="GtkBin"> |
3191 | + <child> |
3192 | + <object class="GtkBox" id="services_page"> |
3193 | + <property name="visible">True</property> |
3194 | + <property name="can-focus">False</property> |
3195 | + <property name="no-show-all">True</property> |
3196 | + <property name="orientation">vertical</property> |
3197 | + <child> |
3198 | + <object class="GtkLabel"> |
3199 | + <property name="visible">True</property> |
3200 | + <property name="can-focus">False</property> |
3201 | + <property name="halign">start</property> |
3202 | + <property name="margin-top">3</property> |
3203 | + <property name="margin-bottom">0</property> |
3204 | + <property name="label" translatable="yes"><b>Ubuntu Pro Services</b></property> |
3205 | + <property name="use-markup">True</property> |
3206 | + <property name="wrap">True</property> |
3207 | + <property name="xalign">0</property> |
3208 | + <attributes> |
3209 | + <attribute name="scale" value="1.4"/> |
3210 | + </attributes> |
3211 | + </object> |
3212 | + </child> |
3213 | + <child> |
3214 | + <object class="GtkSeparator"> |
3215 | + <property name="visible">True</property> |
3216 | + <property name="can-focus">False</property> |
3217 | + <property name="margin-top">10</property> |
3218 | + <property name="margin-bottom">10</property> |
3219 | + </object> |
3220 | + </child> |
3221 | + <child> |
3222 | + <object class="GtkBox"> |
3223 | + <property name="visible">True</property> |
3224 | + <property name="can-focus">False</property> |
3225 | + <property name="no-show-all">True</property> |
3226 | + <child> |
3227 | + <object class="GtkImage" id="checkmark"> |
3228 | + <property name="visible">True</property> |
3229 | + <property name="can-focus">False</property> |
3230 | + <property name="margin-left">10</property> |
3231 | + <property name="margin-right">20</property> |
3232 | + <property name="yalign">0</property> |
3233 | + </object> |
3234 | + </child> |
3235 | + <child> |
3236 | + <object class="GtkBox"> |
3237 | + <property name="visible">True</property> |
3238 | + <property name="can-focus">False</property> |
3239 | + <property name="no-show-all">True</property> |
3240 | + <property name="orientation">vertical</property> |
3241 | + <child> |
3242 | + <object class="GtkLabel"> |
3243 | + <property name="label" translatable="yes">Your subscription:</property> |
3244 | + <property name="margin-bottom">10</property> |
3245 | + <property name="visible">True</property> |
3246 | + <property name="halign">start</property> |
3247 | + <attributes> |
3248 | + <attribute name="scale" value="1.5"/> |
3249 | + </attributes> |
3250 | + </object> |
3251 | + </child> |
3252 | + <child> |
3253 | + <object class="GtkLabel" id="contract_name"> |
3254 | + <property name="visible">True</property> |
3255 | + <property name="margin-bottom">15</property> |
3256 | + <property name="halign">start</property> |
3257 | + </object> |
3258 | + </child> |
3259 | + <child> |
3260 | + <object class="GtkLabel" id="enabled_services_header"> |
3261 | + <property name="label" translatable="yes">List of your enabled services:</property> |
3262 | + <property name="margin-bottom">10</property> |
3263 | + <property name="visible">True</property> |
3264 | + <property name="halign">start</property> |
3265 | + <attributes> |
3266 | + <attribute name="scale" value="1.5"/> |
3267 | + </attributes> |
3268 | + </object> |
3269 | + </child> |
3270 | + <child> |
3271 | + <object class="GtkLabel" id="enabled_services"> |
3272 | + <property name="margin-left">3</property> |
3273 | + <property name="visible">True</property> |
3274 | + <property name="halign">start</property> |
3275 | + </object> |
3276 | + </child> |
3277 | + <child> |
3278 | + <object class="GtkLabel" id="available_services_header"> |
3279 | + <property name="label" translatable="yes">Other available services:</property> |
3280 | + <property name="margin-bottom">10</property> |
3281 | + <property name="visible">True</property> |
3282 | + <property name="halign">start</property> |
3283 | + <attributes> |
3284 | + <attribute name="scale" value="1.5"/> |
3285 | + </attributes> |
3286 | + </object> |
3287 | + </child> |
3288 | + <child> |
3289 | + <object class="GtkLabel" id="available_services"> |
3290 | + <property name="margin-left">3</property> |
3291 | + <property name="visible">True</property> |
3292 | + <property name="halign">start</property> |
3293 | + </object> |
3294 | + </child> |
3295 | + </object> |
3296 | + </child> |
3297 | + </object> |
3298 | + </child> |
3299 | + <child> |
3300 | + <object class="GtkLabel"> |
3301 | + <property name="label" translatable="yes">You can start using Ubuntu Pro features once Ubuntu has finished installing. If you want to change the default enablements for your token you can do so via the ubuntu.com/pro web interface. Alternatively you can change enabled services by going to the Settings menu or the `ua` command-line.</property> |
3302 | + <property name="visible">True</property> |
3303 | + <property name="wrap">True</property> |
3304 | + <property name="halign">start</property> |
3305 | + </object> |
3306 | + </child> |
3307 | + </object> |
3308 | + </child> |
3309 | + </template> |
3310 | +</interface> |
3311 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/meson.build b/gnome-initial-setup/pages/ubuntu-pro/meson.build |
3312 | new file mode 100644 |
3313 | index 0000000..f7b700a |
3314 | --- /dev/null |
3315 | +++ b/gnome-initial-setup/pages/ubuntu-pro/meson.build |
3316 | @@ -0,0 +1,12 @@ |
3317 | +sources += gnome.compile_resources( |
3318 | + 'ubuntupro-resources', |
3319 | + files('ubuntupro.gresource.xml'), |
3320 | + c_name: 'ubuntupro' |
3321 | +) |
3322 | + |
3323 | +sources += files( |
3324 | + 'gis-ubuntupro-page.c', |
3325 | + 'gis-ubuntupro-page.h', |
3326 | + 'utils.c', |
3327 | + 'utils.h', |
3328 | +) |
3329 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro-dark.svg b/gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro-dark.svg |
3330 | new file mode 100644 |
3331 | index 0000000..e33bf48 |
3332 | --- /dev/null |
3333 | +++ b/gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro-dark.svg |
3334 | @@ -0,0 +1,25 @@ |
3335 | +<svg width="132" height="34" viewBox="0 0 132 34" fill="none" xmlns="http://www.w3.org/2000/svg"> |
3336 | +<g clip-path="url(#clip0_1_7165)"> |
3337 | +<path d="M32.24 29.4699C30.94 29.4699 29.91 29.2199 29.14 28.7099C28.37 28.1999 27.81 27.5199 27.47 26.6599C27.13 25.7999 26.96 24.8499 26.96 23.7899V14.6799H28.38V23.5999C28.38 25.1899 28.74 26.3499 29.45 27.0899C30.16 27.8299 31.09 28.1999 32.25 28.1999C33.41 28.1999 34.34 27.8299 35.05 27.0899C35.76 26.3499 36.12 25.1899 36.12 23.5999V14.6799H37.54V23.7899C37.54 24.8499 37.37 25.8099 37.03 26.6599C36.69 27.5099 36.13 28.1999 35.36 28.7099C34.59 29.2199 33.55 29.4699 32.26 29.4699H32.24Z" fill="white"/> |
3338 | +<path d="M44.96 29.41C44.33 29.41 43.77 29.3799 43.28 29.32C42.79 29.26 42.35 29.18 41.99 29.09C41.62 29 41.3 28.91 41.04 28.83V13.2L42.4 12.95V19.01C42.64 18.83 43.02 18.64 43.55 18.44C44.08 18.24 44.69 18.14 45.39 18.14C46.43 18.14 47.32 18.38 48.04 18.86C48.76 19.34 49.32 20.01 49.7 20.86C50.08 21.71 50.27 22.68 50.27 23.78C50.27 24.95 50.05 25.96 49.6 26.8C49.15 27.64 48.54 28.29 47.74 28.74C46.95 29.19 46.02 29.42 44.96 29.42V29.41ZM44.94 28.18C45.72 28.18 46.4 28.01 46.98 27.67C47.56 27.33 48.01 26.83 48.34 26.17C48.67 25.51 48.83 24.71 48.83 23.78C48.83 23.18 48.77 22.62 48.64 22.09C48.51 21.56 48.31 21.09 48.03 20.68C47.75 20.27 47.39 19.95 46.93 19.72C46.47 19.49 45.92 19.38 45.25 19.38C44.58 19.38 44.03 19.49 43.52 19.71C43 19.93 42.63 20.14 42.39 20.34V27.9C42.6 27.96 42.91 28.02 43.33 28.09C43.75 28.16 44.28 28.19 44.94 28.19V28.18Z" fill="white"/> |
3339 | +<path d="M57.2402 29.3699C56.1702 29.3699 55.3202 29.1599 54.6902 28.7499C54.0602 28.3399 53.6202 27.7599 53.3502 27.0199C53.0902 26.2699 52.9502 25.4099 52.9502 24.4199V18.3599H54.3102V23.9799C54.3102 24.9999 54.4102 25.8099 54.6102 26.4099C54.8102 27.0199 55.1402 27.4499 55.6002 27.7299C56.0602 27.9999 56.6702 28.1399 57.4402 28.1399C58.0802 28.1399 58.6402 28.0999 59.1102 28.0399C59.5802 27.9799 59.8802 27.9099 60.0102 27.8499V18.3699H61.3702V28.7899C60.9702 28.8999 60.4202 29.0299 59.7402 29.1699C59.0602 29.3099 58.2202 29.3799 57.2302 29.3799L57.2402 29.3699Z" fill="white"/> |
3340 | +<path d="M64.7598 29.1599V18.7399C65.1598 18.6299 65.7098 18.4999 66.3998 18.3599C67.0898 18.2199 67.9198 18.1499 68.8998 18.1499C69.9998 18.1499 70.8598 18.3599 71.4798 18.7799C72.0998 19.1999 72.5398 19.7799 72.7998 20.5199C73.0598 21.2699 73.1898 22.1299 73.1898 23.1199V29.1599H71.8298V23.5599C71.8298 22.5399 71.7398 21.7299 71.5498 21.1199C71.3598 20.5099 71.0398 20.0699 70.5798 19.7899C70.1198 19.5199 69.4898 19.3799 68.6998 19.3799C68.0598 19.3799 67.5098 19.4199 67.0398 19.4799C66.5698 19.5499 66.2698 19.6099 66.1298 19.6699V29.1499H64.7698L64.7598 29.1599Z" fill="white"/> |
3341 | +<path d="M79.8899 29.3899C78.9999 29.3899 78.2999 29.2299 77.7799 28.9199C77.2599 28.6099 76.8999 28.1399 76.6899 27.5099C76.4799 26.8799 76.3799 26.0899 76.3799 25.1299V15.1899L77.7399 14.9399V18.3699H82.0399V19.5199H77.7399V25.2599C77.7399 26.0799 77.8299 26.6999 78.0099 27.1199C78.1899 27.5399 78.4499 27.8199 78.7899 27.9499C79.1299 28.0899 79.5199 28.1599 79.9699 28.1599C80.5399 28.1599 80.9999 28.0899 81.3499 27.9499C81.6999 27.8099 81.9699 27.6899 82.1599 27.5999L82.4899 28.7299C82.2899 28.8499 81.9499 28.9999 81.4699 29.1599C80.9799 29.3199 80.4499 29.3999 79.8799 29.3999L79.8899 29.3899Z" fill="white"/> |
3342 | +<path d="M88.5898 29.3699C87.5198 29.3699 86.6698 29.1599 86.0398 28.7499C85.4098 28.3399 84.9698 27.7599 84.6998 27.0199C84.4398 26.2699 84.2998 25.4099 84.2998 24.4199V18.3599H85.6598V23.9799C85.6598 24.9999 85.7598 25.8099 85.9598 26.4099C86.1598 27.0199 86.4898 27.4499 86.9498 27.7299C87.4098 27.9999 88.0198 28.1399 88.7898 28.1399C89.4298 28.1399 89.9898 28.0999 90.4598 28.0399C90.9298 27.9799 91.2298 27.9099 91.3598 27.8499V18.3699H92.7198V28.7899C92.3198 28.8999 91.7698 29.0299 91.0898 29.1699C90.4098 29.3099 89.5698 29.3799 88.5798 29.3799L88.5898 29.3699Z" fill="white"/> |
3343 | +<path d="M101.17 29.1601V14.9601C101.67 14.8201 102.26 14.7201 102.94 14.6601C103.61 14.6001 104.24 14.5701 104.83 14.5701C106.86 14.5701 108.38 14.9601 109.39 15.7501C110.4 16.5401 110.9 17.6401 110.9 19.0601C110.9 20.1601 110.65 21.0401 110.14 21.7001C109.63 22.3601 108.9 22.8401 107.96 23.1301C107.01 23.4201 105.88 23.5701 104.55 23.5701H102.59V29.1701H101.17V29.1601ZM102.59 22.3301H104.39C105.41 22.3301 106.29 22.2401 107.04 22.0701C107.79 21.9001 108.38 21.5701 108.79 21.0901C109.21 20.6101 109.42 19.9201 109.42 19.0301C109.42 18.1401 109.2 17.5201 108.76 17.0601C108.32 16.5901 107.76 16.2701 107.07 16.0801C106.38 15.8901 105.65 15.8001 104.89 15.8001C104.37 15.8001 103.93 15.8201 103.55 15.8501C103.17 15.8801 102.85 15.9201 102.59 15.9401V22.3301Z" fill="white"/> |
3344 | +<path d="M113.34 29.1599V18.8599C113.69 18.7099 114.17 18.5499 114.78 18.3899C115.39 18.2299 116.14 18.1499 117.02 18.1499C117.31 18.1499 117.6 18.1699 117.89 18.1999C118.18 18.2399 118.43 18.2799 118.64 18.3199C118.85 18.3599 119.01 18.4099 119.11 18.4599L118.84 19.6299C118.74 19.5699 118.52 19.5099 118.17 19.4499C117.82 19.3899 117.37 19.3599 116.81 19.3599C116.23 19.3599 115.76 19.3999 115.4 19.4799C115.05 19.5599 114.81 19.6299 114.7 19.6899V29.1499H113.34V29.1599Z" fill="white"/> |
3345 | +<path d="M125.12 29.4099C124.16 29.4099 123.31 29.1799 122.57 28.7099C121.83 28.2399 121.25 27.5899 120.83 26.7399C120.41 25.8899 120.19 24.8999 120.19 23.7699C120.19 22.6399 120.4 21.6399 120.83 20.7899C121.25 19.9499 121.84 19.2899 122.57 18.8199C123.3 18.3499 124.16 18.1099 125.12 18.1099C126.08 18.1099 126.93 18.3499 127.68 18.8199C128.42 19.2899 129.01 19.9499 129.42 20.7899C129.84 21.6299 130.05 22.6199 130.05 23.7699C130.05 24.9199 129.84 25.8899 129.42 26.7399C129 27.5899 128.42 28.2499 127.68 28.7099C126.93 29.1799 126.08 29.4099 125.12 29.4099ZM125.12 28.1799C125.83 28.1799 126.45 27.9999 126.97 27.6399C127.49 27.2799 127.9 26.7699 128.18 26.0999C128.47 25.4399 128.61 24.6599 128.61 23.7699C128.61 22.8799 128.47 22.0799 128.18 21.4199C127.89 20.7599 127.49 20.2499 126.97 19.8799C126.45 19.5199 125.83 19.3399 125.12 19.3399C124.41 19.3399 123.79 19.5199 123.27 19.8799C122.75 20.2399 122.34 20.7499 122.06 21.4199C121.77 22.0799 121.63 22.8699 121.63 23.7699C121.63 24.6699 121.77 25.4399 122.06 26.0999C122.35 26.7599 122.75 27.2699 123.27 27.6399C123.79 27.9999 124.41 28.1799 125.12 28.1799Z" fill="white"/> |
3346 | +<path d="M21.5 0H0.5V32H21.5V0Z" fill="#E95420"/> |
3347 | +<path d="M5.29988 23.32C6.49834 23.32 7.46988 22.3484 7.46988 21.15C7.46988 19.9515 6.49834 18.98 5.29988 18.98C4.10142 18.98 3.12988 19.9515 3.12988 21.15C3.12988 22.3484 4.10142 23.32 5.29988 23.32Z" fill="white"/> |
3348 | +<path d="M14.3599 18.56C15.5584 18.56 16.5299 17.5884 16.5299 16.39C16.5299 15.1915 15.5584 14.22 14.3599 14.22C13.1615 14.22 12.1899 15.1915 12.1899 16.39C12.1899 17.5884 13.1615 18.56 14.3599 18.56Z" fill="white"/> |
3349 | +<path d="M10.2 26.75C8.62998 26.41 7.32998 25.41 6.58998 24C6.00998 24.26 5.35998 24.34 4.72998 24.23C5.61998 26.42 7.50998 28 9.82998 28.5C10.34 28.61 10.86 28.66 11.37 28.66C10.97 28.14 10.75 27.5 10.73 26.84C10.55 26.82 10.37 26.79 10.2 26.75Z" fill="white"/> |
3350 | +<path d="M13.8702 28.9301C15.0687 28.9301 16.0402 27.9585 16.0402 26.7601C16.0402 25.5616 15.0687 24.5901 13.8702 24.5901C12.6717 24.5901 11.7002 25.5616 11.7002 26.7601C11.7002 27.9585 12.6717 28.9301 13.8702 28.9301Z" fill="white"/> |
3351 | +<path d="M16.8898 25.9601C17.5698 25.1101 18.0398 24.1001 18.2698 23.0301C18.6698 21.1601 18.2998 19.2001 17.2398 17.6101C16.9898 18.2001 16.5598 18.7001 16.0198 19.0401C16.6098 20.1501 16.7898 21.4201 16.5198 22.6501C16.3898 23.2501 16.1598 23.8201 15.8398 24.3301C16.3498 24.7501 16.7098 25.3101 16.8798 25.9501L16.8898 25.9601Z" fill="white"/> |
3352 | +<path d="M5.12988 18.04C5.18988 18.04 5.23988 18.04 5.29988 18.04C5.51988 18.04 5.73988 18.06 5.95988 18.11C6.30988 18.19 6.64988 18.32 6.94988 18.51C7.92988 17.1 9.50988 16.26 11.2199 16.23C11.2199 16.07 11.2499 15.9 11.2899 15.74C11.3899 15.27 11.5899 14.84 11.8799 14.47C9.14988 14.25 6.48988 15.66 5.13988 18.05L5.12988 18.04Z" fill="white"/> |
3353 | +</g> |
3354 | +<defs> |
3355 | +<clipPath id="clip0_1_7165"> |
3356 | +<rect width="130.71" height="34" fill="white" transform="translate(0.5)"/> |
3357 | +</clipPath> |
3358 | +</defs> |
3359 | +</svg> |
3360 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro.svg b/gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro.svg |
3361 | new file mode 100644 |
3362 | index 0000000..d377e41 |
3363 | --- /dev/null |
3364 | +++ b/gnome-initial-setup/pages/ubuntu-pro/ubuntu-pro.svg |
3365 | @@ -0,0 +1 @@ |
3366 | +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1444.23 360.27"><defs><style>.cls-1{fill:#e95420;}.cls-2{fill:#fff;}.cls-3{fill:#111;}</style></defs><rect class="cls-1" width="233.93" height="360.27"/><circle class="cls-2" cx="52.26" cy="238.51" r="24.44"/><circle class="cls-2" cx="154.06" cy="184.91" r="24.44"/><path class="cls-2" d="M107.39,301.42a59.52,59.52,0,0,1-40.6-31A35.22,35.22,0,0,1,45.89,273a80.08,80.08,0,0,0,74.65,49.8,35,35,0,0,1-7.16-20.44A60.26,60.26,0,0,1,107.39,301.42Z"/><circle class="cls-2" cx="148.55" cy="301.55" r="24.44"/><path class="cls-2" d="M182.56,292.58a79.94,79.94,0,0,0,4-93.83,35.16,35.16,0,0,1-13.74,16.09,60,60,0,0,1-2,59.53A35,35,0,0,1,182.56,292.58Z"/><path class="cls-2" d="M50.37,203.46c.62,0,1.24-.05,1.87-.05a35.36,35.36,0,0,1,7.37.78,35,35,0,0,1,11.16,4.5,59.63,59.63,0,0,1,48-25.68,36.52,36.52,0,0,1,.74-5.5,35.3,35.3,0,0,1,6.68-14.32A80.38,80.38,0,0,0,50.37,203.46Z"/><path class="cls-3" d="M347.78,331.73q-16.27,0-27.71-5a47.72,47.72,0,0,1-18.52-13.68,54.81,54.81,0,0,1-10.26-20.41,95.22,95.22,0,0,1-3.19-25.12V164.73h16V265.45a75.46,75.46,0,0,0,3.19,23.23,44.78,44.78,0,0,0,8.84,16.16,34.55,34.55,0,0,0,13.68,9.44,54.06,54.06,0,0,0,35.86,0,34.55,34.55,0,0,0,13.68-9.44,44.78,44.78,0,0,0,8.84-16.16,75.46,75.46,0,0,0,3.19-23.23V164.73h16V267.57a95.22,95.22,0,0,1-3.19,25.12A54.81,54.81,0,0,1,394,313.1a47.76,47.76,0,0,1-18.51,13.68Q364.06,331.73,347.78,331.73Z"/><path class="cls-3" d="M460.55,213.56q4-3.06,12.85-6.49a58,58,0,0,1,20.88-3.42,55.7,55.7,0,0,1,23.47,4.72,48.76,48.76,0,0,1,17.33,13.21,58.28,58.28,0,0,1,10.74,20.17,85.49,85.49,0,0,1,3.65,25.59A76.4,76.4,0,0,1,545.11,294,57.25,57.25,0,0,1,532.84,314,52.66,52.66,0,0,1,514,326.66,65.48,65.48,0,0,1,489.56,331q-16.28,0-26.89-2.12a137.63,137.63,0,0,1-17.45-4.48V148l15.33-2.83Zm0,100.25A68.84,68.84,0,0,0,471,316.05a127.35,127.35,0,0,0,18.28,1.06q19.81,0,31.85-12.86t12-36.91a84.07,84.07,0,0,0-2.13-19.23,44.87,44.87,0,0,0-6.84-15.8,34.25,34.25,0,0,0-12.38-10.73q-7.67-4-19-4a49.31,49.31,0,0,0-10.38,1.06,61.57,61.57,0,0,0-9.19,2.71,51,51,0,0,0-12.74,7.08Z"/><path class="cls-3" d="M673.56,324q-6.84,1.89-18.4,4.24a144.38,144.38,0,0,1-28.3,2.36q-13.68,0-22.88-4a37.07,37.07,0,0,1-14.86-11.32A45.88,45.88,0,0,1,581,297.53a98.64,98.64,0,0,1-2.47-22.88v-68.4h15.33V269.7a108.25,108.25,0,0,0,1.88,21.93q1.89,9,6.14,14.51a23.86,23.86,0,0,0,11,8,47.64,47.64,0,0,0,16.39,2.48,132.49,132.49,0,0,0,18.87-1.18c5.34-.79,8.73-1.5,10.14-2.13V206.25h15.33Z"/><path class="cls-3" d="M710.26,210.49q6.84-1.87,18.4-4.24a144.38,144.38,0,0,1,28.3-2.36q13.92,0,23.24,4a35.73,35.73,0,0,1,14.86,11.44,46.84,46.84,0,0,1,7.9,17.81A103.44,103.44,0,0,1,805.32,260v68.16H790V265A115.58,115.58,0,0,0,788.22,243a36.61,36.61,0,0,0-5.9-14.62,23,23,0,0,0-10.85-8.14q-6.72-2.47-16.87-2.47A128.49,128.49,0,0,0,735.85,219q-7.9,1.17-10.26,2.12V328.19H710.26Z"/><path class="cls-3" d="M855.39,206.25H904v13H855.39v64.87A65.79,65.79,0,0,0,857.16,301a23.36,23.36,0,0,0,5.07,10,16,16,0,0,0,8,4.72,42.53,42.53,0,0,0,10.38,1.18q9.66,0,15.56-2.24a67,67,0,0,0,9.2-4.13l3.78,12.74q-3.31,2.13-11.56,4.83a57.11,57.11,0,0,1-17.93,2.72q-11.32,0-19-3a27.48,27.48,0,0,1-12.26-9,36.72,36.72,0,0,1-6.49-15,104.2,104.2,0,0,1-1.88-21.23V170.4l15.33-2.83Z"/><path class="cls-3" d="M1023.33,324q-6.86,1.89-18.4,4.24a144.49,144.49,0,0,1-28.31,2.36q-13.68,0-22.88-4a37.14,37.14,0,0,1-14.86-11.32,45.87,45.87,0,0,1-8.13-17.69,98.62,98.62,0,0,1-2.48-22.88v-68.4H943.6V269.7a108.17,108.17,0,0,0,1.89,21.93q1.89,9,6.13,14.51a23.91,23.91,0,0,0,11,8A47.64,47.64,0,0,0,979,316.64a132.49,132.49,0,0,0,18.87-1.18q8-1.18,10.14-2.13V206.25h15.34Z"/><path class="cls-3" d="M1156.68,163.32q34.68,0,51.66,13.21t17,37.5q0,13.92-5,23.71a40.35,40.35,0,0,1-14.15,15.8q-9.21,6-22.53,8.73a151.33,151.33,0,0,1-30.07,2.71h-22.17v63.21h-16V167.8a115.14,115.14,0,0,1,19.93-3.42Q1146.77,163.32,1156.68,163.32Zm.71,13.92q-9,0-15.21.59t-10.73,1.06v72.17h20.28a163.68,163.68,0,0,0,23.47-1.53,52.38,52.38,0,0,0,17.93-5.66,28.63,28.63,0,0,0,11.44-11.44q4-7.31,4-18.63,0-10.85-4.37-17.93a32.14,32.14,0,0,0-11.56-11.2,50.62,50.62,0,0,0-16.39-5.78A106.64,106.64,0,0,0,1157.39,177.24Z"/><path class="cls-3" d="M1292.85,203.89a82.18,82.18,0,0,1,14.27,1.18,43.81,43.81,0,0,1,9.32,2.36l-3.07,13.21a34.1,34.1,0,0,0-7.66-2,87.42,87.42,0,0,0-15.22-1.06,71.62,71.62,0,0,0-15.92,1.42,44.62,44.62,0,0,0-7.9,2.35V328.19h-15.33V211.91a113,113,0,0,1,16.27-5.31Q1278,203.9,1292.85,203.89Z"/><path class="cls-3" d="M1438.5,267.34a78.87,78.87,0,0,1-4.13,26.18,58.25,58.25,0,0,1-11.56,20.05,52.56,52.56,0,0,1-17.57,12.85,56.86,56.86,0,0,1-44.81,0,52.6,52.6,0,0,1-17.58-12.85,58.39,58.39,0,0,1-11.55-20.05,85,85,0,0,1,0-52.36A59.72,59.72,0,0,1,1342.85,221a51.86,51.86,0,0,1,17.58-13,56.86,56.86,0,0,1,44.81,0,51.82,51.82,0,0,1,17.57,13,59.57,59.57,0,0,1,11.56,20.17A78.87,78.87,0,0,1,1438.5,267.34Zm-16.28,0q0-22.87-10.61-36.44t-28.78-13.57q-18.16,0-28.77,13.57t-10.62,36.44q0,22.88,10.62,36.32t28.77,13.45q18.17,0,28.78-13.45T1422.22,267.34Z"/></svg> |
3367 | \ No newline at end of file |
3368 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/ubuntupro.gresource.xml b/gnome-initial-setup/pages/ubuntu-pro/ubuntupro.gresource.xml |
3369 | new file mode 100644 |
3370 | index 0000000..9257186 |
3371 | --- /dev/null |
3372 | +++ b/gnome-initial-setup/pages/ubuntu-pro/ubuntupro.gresource.xml |
3373 | @@ -0,0 +1,14 @@ |
3374 | +<?xml version="1.0" encoding="UTF-8"?> |
3375 | +<gresources> |
3376 | + <gresource prefix="/org/gnome/initial-setup"> |
3377 | + <file preprocess="xml-stripblanks" alias="gis-ubuntupro-page.ui">gis-ubuntupro-page.ui</file> |
3378 | + <file preprocess="xml-stripblanks" alias="gis-ubuntupro-offer-page.ui">gis-ubuntupro-offer-page.ui</file> |
3379 | + <file preprocess="xml-stripblanks" alias="gis-ubuntupro-attach-page.ui">gis-ubuntupro-attach-page.ui</file> |
3380 | + <file preprocess="xml-stripblanks" alias="gis-ubuntupro-services-page.ui">gis-ubuntupro-services-page.ui</file> |
3381 | + <file alias="ubuntu-pro-dark.svg">ubuntu-pro-dark.svg</file> |
3382 | + <file alias="ubuntu-pro.svg">ubuntu-pro.svg</file> |
3383 | + <file alias="checkmark.svg">checkmark.svg</file> |
3384 | + <file alias="fail.svg">fail.svg</file> |
3385 | + </gresource> |
3386 | +</gresources> |
3387 | + |
3388 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/utils.c b/gnome-initial-setup/pages/ubuntu-pro/utils.c |
3389 | new file mode 100644 |
3390 | index 0000000..e2f1509 |
3391 | --- /dev/null |
3392 | +++ b/gnome-initial-setup/pages/ubuntu-pro/utils.c |
3393 | @@ -0,0 +1,123 @@ |
3394 | +#include <libsoup/soup.h> |
3395 | +#include "gis-ubuntupro-page.h" |
3396 | + |
3397 | +gboolean |
3398 | +parse_ua_status(gchar **contents, gsize *len) |
3399 | +{ |
3400 | + g_autoptr(GError) error = NULL; |
3401 | + |
3402 | + if (!g_file_get_contents("/var/lib/ubuntu-advantage/status.json", |
3403 | + contents, len, &error)) { |
3404 | + g_warning("Unable to read pro status: %s\n", error->message); |
3405 | + return FALSE; |
3406 | + } |
3407 | + return TRUE; |
3408 | +} |
3409 | + |
3410 | +gboolean |
3411 | +get_ubuntu_advantage_attached(gboolean *attached) |
3412 | +{ |
3413 | + g_autoptr(GError) error = NULL; |
3414 | + g_autoptr(GDBusConnection) bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); |
3415 | + if (bus == NULL) { |
3416 | + g_warning ("Failed to get system bus: %s", error->message); |
3417 | + return FALSE; |
3418 | + } |
3419 | + |
3420 | + g_autoptr(GVariant) result = g_dbus_connection_call_sync (bus, |
3421 | + "com.canonical.UbuntuAdvantage", |
3422 | + "/com/canonical/UbuntuAdvantage/Manager", |
3423 | + "org.freedesktop.DBus.Properties", |
3424 | + "Get", |
3425 | + g_variant_new ("(ss)", "com.canonical.UbuntuAdvantage.Manager", "Attached"), |
3426 | + G_VARIANT_TYPE ("(v)"), |
3427 | + G_DBUS_CALL_FLAGS_NONE, |
3428 | + -1, |
3429 | + NULL, |
3430 | + &error); |
3431 | + if (result == NULL) { |
3432 | + g_warning ("Failed to contact Ubuntu Advantage D-Bus service: %s", error->message); |
3433 | + return FALSE; |
3434 | + } |
3435 | + |
3436 | + g_autoptr(GVariant) value = NULL; |
3437 | + g_variant_get (result, "(v)", &value); |
3438 | + if (!g_variant_is_of_type (value, G_VARIANT_TYPE("b"))) { |
3439 | + g_warning ("Attached property has wrong type"); |
3440 | + return FALSE; |
3441 | + } |
3442 | + g_variant_get (value, "b", attached); |
3443 | + |
3444 | + return TRUE; |
3445 | +} |
3446 | + |
3447 | +char * |
3448 | +get_item (const char *buffer, const char *name) |
3449 | +{ |
3450 | + g_autofree gchar *label = NULL; |
3451 | + gchar *start = NULL, *end = NULL; |
3452 | + gchar end_char; |
3453 | + |
3454 | + label = g_strconcat (name, "=", NULL); |
3455 | + if ((start = strstr (buffer, label)) != NULL) { |
3456 | + start += strlen (label); |
3457 | + end_char = '\n'; |
3458 | + if (*start == '"') { |
3459 | + start++; |
3460 | + end_char = '"'; |
3461 | + } |
3462 | + end = strchr (start, end_char); |
3463 | + } |
3464 | + |
3465 | + if (start != NULL && end != NULL) |
3466 | + return g_strndup (start, end - start); |
3467 | + else |
3468 | + return NULL; |
3469 | +} |
3470 | + |
3471 | +gboolean |
3472 | +is_lts () |
3473 | +{ |
3474 | + g_autofree gchar *buffer = NULL; |
3475 | + g_autofree gchar *version = NULL; |
3476 | + |
3477 | + if (g_file_get_contents ("/etc/os-release", &buffer, NULL, NULL)) |
3478 | + version = get_item (buffer, "VERSION"); |
3479 | + |
3480 | + return version && g_strrstr (version, "LTS") != NULL; |
3481 | +} |
3482 | + |
3483 | +gboolean |
3484 | +is_ubuntupro_supported () |
3485 | +{ |
3486 | + return is_lts (); |
3487 | +} |
3488 | + |
3489 | +/* Routine from Gnome Control Center |
3490 | + * https://gitlab.gnome.org/GNOME/gnome-control-center/-/commit/a3b8964a */ |
3491 | +gboolean |
3492 | +is_dark_theme (GtkWidget *widget) |
3493 | +{ |
3494 | + GdkScreen *screen; |
3495 | + GtkSettings *settings; |
3496 | + g_autofree char *theme_name = NULL; |
3497 | + |
3498 | + theme_name = g_strdup (g_getenv ("GTK_THEME")); |
3499 | + if (theme_name != NULL) { |
3500 | + return g_str_has_suffix (theme_name, "dark"); |
3501 | + } |
3502 | + |
3503 | + screen = gtk_widget_get_screen (GTK_WIDGET (widget)); |
3504 | + settings = gtk_settings_get_for_screen (screen); |
3505 | + |
3506 | + g_object_get (settings, "gtk-theme-name", &theme_name, NULL); |
3507 | + return theme_name != NULL && g_str_has_suffix (theme_name, "dark"); |
3508 | +} |
3509 | + |
3510 | +void |
3511 | +itemize(gchar *str, const gchar *append, gsize len) |
3512 | +{ |
3513 | + g_strlcat(str, "• ", len); |
3514 | + g_strlcat(str, append, len); |
3515 | + g_strlcat(str, "\n", len); |
3516 | +} |
3517 | diff --git a/gnome-initial-setup/pages/ubuntu-pro/utils.h b/gnome-initial-setup/pages/ubuntu-pro/utils.h |
3518 | new file mode 100644 |
3519 | index 0000000..ceefe72 |
3520 | --- /dev/null |
3521 | +++ b/gnome-initial-setup/pages/ubuntu-pro/utils.h |
3522 | @@ -0,0 +1,7 @@ |
3523 | +gboolean parse_ua_status(gchar**, gsize*); |
3524 | +gboolean get_ubuntu_advantage_attached(gboolean*); |
3525 | +char *get_item(const char*, const char*); |
3526 | +gboolean is_lts(); |
3527 | +gboolean is_ubuntupro_supported(); |
3528 | +gboolean is_dark_theme(GtkWidget*); |
3529 | +void itemize(gchar*, const gchar*, gsize); |
3530 | diff --git a/po/POTFILES.in b/po/POTFILES.in |
3531 | index 9b1b23f..43dbabb 100644 |
3532 | --- a/po/POTFILES.in |
3533 | +++ b/po/POTFILES.in |
3534 | @@ -1,4 +1,3 @@ |
3535 | -data/com.ubuntu.welcome.policy.in |
3536 | data/gnome-initial-setup-first-login.desktop.in.in |
3537 | data/gnome-initial-setup.desktop.in.in |
3538 | gnome-initial-setup/cc-common-language.c |
3539 | @@ -37,17 +36,16 @@ gnome-initial-setup/pages/software/gis-software-page.c |
3540 | gnome-initial-setup/pages/software/gis-software-page.ui |
3541 | gnome-initial-setup/pages/summary/gis-summary-page.c |
3542 | gnome-initial-setup/pages/summary/gis-summary-page.ui |
3543 | -gnome-initial-setup/pages/timezone/gis-location-entry.c |
3544 | gnome-initial-setup/pages/timezone/gis-timezone-page.c |
3545 | gnome-initial-setup/pages/timezone/gis-timezone-page.ui |
3546 | +gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-attach-page.ui |
3547 | +gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-offer-page.ui |
3548 | +gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-page.c |
3549 | +gnome-initial-setup/pages/ubuntu-pro/gis-ubuntupro-services-page.ui |
3550 | gnome-initial-setup/pages/welcome/gis-welcome-page.c |
3551 | gnome-initial-setup/pages/welcome/gis-welcome-page.ui |
3552 | gnome-initial-setup/pages/timezone/gis-timezone-page.ui |
3553 | gnome-initial-setup/pages/ubuntu-report/gis-ubuntu-report-page.c |
3554 | gnome-initial-setup/pages/ubuntu-report/gis-ubuntu-report-page.ui |
3555 | -gnome-initial-setup/pages/livepatch/gis-auth-dialog.c |
3556 | -gnome-initial-setup/pages/livepatch/gis-auth-dialog.ui |
3557 | -gnome-initial-setup/pages/livepatch/gis-livepatch-page.c |
3558 | -gnome-initial-setup/pages/livepatch/gis-livepatch-page.ui |
3559 | gnome-initial-setup/pages/apps/gis-apps-page.c |
3560 | gnome-initial-setup/pages/apps/gis-apps-page.ui |
Copying Robert's comment from superseded review https:/ /code.launchpad .net/~nteodosio /+git/ubuntu- pro/+merge/ 434494:
"""
I'm very confused as to what this PR is doing - it's proposing merging two branches you control, not merging into the gnome-initial-setup branch that matches a released version. The information below also shows merge conflicts, so it seems broken.
I would recommend that you squash all the merges together if this is a single change (you can make a backup branch containing all your commits if you want to refer to them later). It is much harder to review with all these commits.
Just looking at you ubuntupro branch and the files in gnome-initial- setup/pages/ ubuntu- pro/: page-1" -> "gs-ubuntupro- services- page" ua_services( ) should use g_autofree/ g_autoptr for variables. This will allow you to remove the goto and just return directly from the function. g_autoptr. ge1Private contains unused cancellable, apply_complete_ callback, apply_complete_data fields.
- It would be easier to read if the three pages were in three .c files.
- The pages would be clearer if they had names that related to what they did, i.e. "gs-ubuntupro-
- The .ui files contain unused id properties.
- The .ui files contain unused position properties (these make future changes more complicated).
- RestJSONResponse is only used inside the .c files, but is defined in the header - if this is private it doesn't need to be exposed like this.
- display_
- Lots of other functions don't use g_autofree/
- _GisUbuntuProPa
- contractToken should be called contract_token.
- You store the PIN in a variable and then set it in the GtkLabel - this is unnecessary and would be simpler just to store in the GtkLabel directly. Otherwise you have the same data in two places (which could get out of sync).
- There's no dispose methods for the page classes, so they leak data.
- You've used 543210 as a timeout, if you want no timeout use G_MAXINT.
- The labels set in update_gui() aren't translatable.
- I haven't been able to get it to compile here or seen the designs so I haven't been able to review that.
"""