Merge lp:~mvo/ubuntu-app-launch/hide-apps-on-missing-framework into lp:ubuntu-app-launch/14.04

Proposed by Michael Vogt
Status: Work in progress
Proposed branch: lp:~mvo/ubuntu-app-launch/hide-apps-on-missing-framework
Merge into: lp:ubuntu-app-launch/14.04
Diff against target: 189 lines (+98/-10)
4 files modified
desktop-hook.c (+38/-0)
helpers.c (+42/-10)
helpers.h (+5/-0)
tests/helper-test.cc (+13/-0)
To merge this branch: bzr merge lp:~mvo/ubuntu-app-launch/hide-apps-on-missing-framework
Reviewer Review Type Date Requested Status
Colin Watson Needs Information
PS Jenkins bot (community) continuous-integration Needs Fixing
Indicator Applet Developers Pending
Review via email: mp+218564@code.launchpad.net

Commit message

Hide apps if the framework requirements are not/no longer meet (LP: #1271944)

Description of the change

This branch fixes bug #1271944 (as suggested by Colin) - when the desktop hook is run at system and session startup it will check if the framework requirements are meet. If that is not the case, the click package is hidden from the available applications. Once the frameworks becomes available again the click is made available again.

Please let me know what you think, happy to change the code/improve tests etc. There is currently some code duplication around the handling of TEST_CLICK_{DB,USER}. If that is a concern I can move it into a helper function "ClickUser * click_get_user()" or something similar.

Thanks,
 Michael

To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote :

Please also let me know if you prefer the branch as a single commit instead of the current 4 (for a cleaner history).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:148
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~mvo/upstart-app-launch/hide-apps-on-missing-framework/+merge/218564/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/upstart-app-launch-ci/262/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/upstart-app-launch-utopic-amd64-ci/1
    SUCCESS: http://jenkins.qa.ubuntu.com/job/upstart-app-launch-utopic-armhf-ci/1
    SUCCESS: http://jenkins.qa.ubuntu.com/job/upstart-app-launch-utopic-i386-ci/1

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/upstart-app-launch-ci/262/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Colin Watson (cjwatson) wrote :

This probably does handle the narrow issue at hand of removing the affected .desktop files, but I think it's a mistake to do this in upstart-app-launch. Other hooks may be affected, and we shouldn't have to have every hook handle this independently in order to get consistent results. I would much prefer us to handle this centrally instead.

Why not have click's hook code simply remove the symlinks associated with apps whose framework dependencies aren't satisfied and then re-run the Exec command for each affected hook? The hook's Exec command is supposed to bring the system into sync with the contents of the symlink farm populated by click, so removing entries from that symlink farm should be sufficient to make the .desktop files vanish when the Exec command is run, without the need to change upstart-app-launch at all.

review: Needs Information
Revision history for this message
Michael Vogt (mvo) wrote :

Thanks for your feedback Colin! I misunderstood the purpose of upstart-app-launch and it does indeed make more sense to have it in the central click hook code. I will rework the code accordingly.

Unmerged revisions

148. By Michael Vogt

remove get_pkgdir_from_appid() helper which was misguided

147. By Michael Vogt

add tests, make code more consitent

146. By Michael Vogt

fix error handling in get_manifest_for_app_id()

145. By Michael Vogt

unregister a click application if the required framework is not/no longer available

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'desktop-hook.c'
2--- desktop-hook.c 2014-03-07 12:33:01 +0000
3+++ desktop-hook.c 2014-05-07 08:02:18 +0000
4@@ -105,6 +105,40 @@
5 return time;
6 }
7
8+/* Check if the required frameworks are available for the given appid */
9+static gboolean
10+has_required_frameworks(app_state_t * state)
11+{
12+ JsonObject * manifest = NULL;
13+ gchar *framework = NULL;
14+ gboolean res = FALSE;
15+
16+ manifest = get_manifest_for_appid(state->app_id);
17+ if (manifest == NULL) {
18+ g_warning("Manifest '%s' can not be read", state->app_id);
19+ goto out;
20+ }
21+ if (!json_object_has_member(manifest, "framework")) {
22+ g_warning("Manifest '%s' doesn't have an framework section", state->app_id);
23+ goto out;
24+ }
25+ framework = g_strdup(json_object_get_string_member(manifest, "framework"));
26+ if(framework == NULL) {
27+ g_warning("Manifest '%s' doesn't have a framework", state->app_id);
28+ goto out;
29+ }
30+ // FIXME: support multiple frameworks
31+ res = click_framework_has_framework(framework);
32+
33+ out:
34+ if (manifest != NULL)
35+ json_object_unref(manifest);
36+ g_free(framework);
37+ return res;
38+}
39+
40+
41+
42 /* Look at an click package entry */
43 void
44 add_click_package (const gchar * dir, const gchar * name, GArray * app_array)
45@@ -120,6 +154,10 @@
46 state->has_click = TRUE;
47 state->click_modified = modified_time(dir, name);
48
49+ // unregister if the required framework requirements are not meet
50+ if (!has_required_frameworks(state))
51+ state->has_click = FALSE;
52+
53 g_free(appid);
54
55 return;
56
57=== modified file 'helpers.c'
58--- helpers.c 2014-03-12 00:28:05 +0000
59+++ helpers.c 2014-05-07 08:02:18 +0000
60@@ -57,10 +57,8 @@
61 return TRUE;
62 }
63
64-/* Take a manifest, parse it, find the application and
65- and then return the path to the desktop file */
66-gchar *
67-manifest_to_desktop (const gchar * app_dir, const gchar * app_id)
68+JsonObject *
69+get_manifest_for_appid(const gchar * app_id)
70 {
71 gchar * package = NULL;
72 gchar * application = NULL;
73@@ -68,7 +66,6 @@
74 ClickDB * db = NULL;
75 ClickUser * user = NULL;
76 JsonObject * manifest = NULL;
77- gchar * desktoppath = NULL;
78 GError * error = NULL;
79
80 if (!app_id_to_triplet(app_id, &package, &application, &version)) {
81@@ -97,14 +94,51 @@
82
83 if (!json_object_has_member(manifest, "version")) {
84 g_warning("Manifest '%s' doesn't have a version", package);
85+ json_object_unref(manifest);
86+ manifest = NULL;
87 goto manifest_out;
88 }
89
90 if (g_strcmp0(json_object_get_string_member(manifest, "version"), version) != 0) {
91 g_warning("Manifest '%s' version '%s' doesn't match AppID version '%s'", package, json_object_get_string_member(manifest, "version"), version);
92- goto manifest_out;
93- }
94-
95+ json_object_unref(manifest);
96+ manifest = NULL;
97+ goto manifest_out;
98+ }
99+
100+manifest_out:
101+ if (error != NULL)
102+ g_error_free(error);
103+ g_clear_object(&user);
104+ g_clear_object(&db);
105+ g_free(package);
106+ g_free(application);
107+ g_free(version);
108+
109+ return manifest;
110+}
111+
112+/* Take a manifest, parse it, find the application and
113+ and then return the path to the desktop file */
114+gchar *
115+manifest_to_desktop (const gchar * app_dir, const gchar * app_id)
116+{
117+ gchar * desktoppath = NULL;
118+ GError * error = NULL;
119+ gchar * package = NULL;
120+ gchar * application = NULL;
121+ gchar * version = NULL;
122+ JsonObject * manifest = NULL;
123+
124+ if (!app_id_to_triplet(app_id, &package, &application, &version)) {
125+ g_warning("Unable to parse triplet: %s", app_id);
126+ return NULL;
127+ }
128+
129+ manifest = get_manifest_for_appid(app_id);
130+ if (manifest == NULL) {
131+ goto manifest_out;
132+ }
133 if (!json_object_has_member(manifest, "hooks")) {
134 g_warning("Manifest '%s' doesn't have an hooks section", package);
135 goto manifest_out;
136@@ -148,8 +182,6 @@
137 g_error_free(error);
138 if (manifest != NULL)
139 json_object_unref(manifest);
140- g_clear_object(&user);
141- g_clear_object(&db);
142 g_free(package);
143 g_free(application);
144 g_free(version);
145
146=== modified file 'helpers.h'
147--- helpers.h 2014-02-03 18:27:58 +0000
148+++ helpers.h 2014-05-07 08:02:18 +0000
149@@ -18,6 +18,7 @@
150 */
151
152 #include <glib.h>
153+#include <json-glib/json-glib.h>
154
155 gboolean app_id_to_triplet (const gchar * app_id,
156 gchar ** package,
157@@ -37,7 +38,11 @@
158 void set_confined_envvars (const gchar * package,
159 const gchar * app_dir);
160
161+JsonObject * get_manifest_for_appid (const gchar * app_id);
162+
163+
164 typedef struct _handshake_t handshake_t;
165 handshake_t * starting_handshake_start (const gchar * app_id);
166 void starting_handshake_wait (handshake_t * handshake);
167
168+
169
170=== modified file 'tests/helper-test.cc'
171--- tests/helper-test.cc 2014-03-12 00:28:05 +0000
172+++ tests/helper-test.cc 2014-05-07 08:02:18 +0000
173@@ -453,3 +453,16 @@
174
175 return;
176 }
177+
178+TEST_F(HelperTest, GetManifestForAppid)
179+{
180+ JsonObject *manifest = NULL;
181+
182+ g_setenv("TEST_CLICK_DB", "click-db-dir", TRUE);
183+ g_setenv("TEST_CLICK_USER", "test-user", TRUE);
184+
185+ manifest = get_manifest_for_appid("com.test.good_application_1.2.3");
186+ ASSERT_STREQ(json_object_get_string_member(manifest, "version"),
187+ "1.2.3");
188+ json_object_unref(manifest);
189+}

Subscribers

People subscribed via source and target branches