Merge lp:~ted/ubuntu-app-launch/rm-rf-click into lp:ubuntu-app-launch
- rm-rf-click
- Merge into trunk.17.04
Status: | Merged |
---|---|
Approved by: | Ken VanDine |
Approved revision: | 391 |
Merged at revision: | 304 |
Proposed branch: | lp:~ted/ubuntu-app-launch/rm-rf-click |
Merge into: | lp:ubuntu-app-launch |
Prerequisite: | lp:~ted/ubuntu-app-launch/rm-rf-upstart |
Diff against target: |
7412 lines (+1691/-4059) 62 files modified
CMakeLists.txt (+0/-33) debian/control (+0/-3) debian/rules (+1/-4) desktop-hook.c (+0/-536) docs/index.rst (+0/-23) libubuntu-app-launch/CMakeLists.txt (+7/-18) libubuntu-app-launch/app-info.c (+0/-277) libubuntu-app-launch/app-store-base.cpp (+6/-15) libubuntu-app-launch/app-store-click.cpp (+0/-248) libubuntu-app-launch/app-store-click.h (+0/-60) libubuntu-app-launch/app-store-snap.cpp (+19/-1) libubuntu-app-launch/application-impl-base.cpp (+1/-1) libubuntu-app-launch/application-impl-click.cpp (+0/-189) libubuntu-app-launch/application-impl-click.h (+0/-82) libubuntu-app-launch/glib-thread.cpp (+28/-17) libubuntu-app-launch/glib-thread.h (+8/-6) libubuntu-app-launch/helper.cpp (+28/-5) libubuntu-app-launch/jobs-base.cpp (+68/-33) libubuntu-app-launch/jobs-systemd.cpp (+19/-7) libubuntu-app-launch/registry-impl.cpp (+8/-133) libubuntu-app-launch/registry-impl.h (+7/-12) libubuntu-app-launch/second-exec-core.c (+1/-1) libubuntu-app-launch/type-tagger.h (+8/-0) libubuntu-app-launch/ubuntu-app-launch.cpp (+16/-6) libubuntu-app-launch/utils-shared.c (+1/-1) libubuntu-app-launch/utils.c (+1/-102) libubuntu-app-launch/utils.h (+0/-2) tests/CMakeLists.txt (+5/-18) tests/application-info-desktop.cpp (+5/-4) tests/applications/foo.desktop (+1/-1) tests/click-app-dir/.click/info/chatter.robert-ancell.manifest (+0/-8) tests/click-app-dir/.click/info/com.test.bad-version.manifest (+0/-8) tests/click-app-dir/.click/info/com.test.good.manifest (+0/-8) tests/click-app-dir/.click/info/com.test.mir.manifest (+0/-11) tests/click-app-dir/.click/info/com.test.multiple.manifest (+0/-20) tests/click-app-dir/.click/info/com.test.no-app.manifest (+0/-8) tests/click-app-dir/.click/info/com.test.no-hooks.manifest (+0/-8) tests/click-app-dir/.click/info/com.test.no-json.manifest (+0/-5) tests/click-app-dir/.click/info/com.test.no-object.manifest (+0/-6) tests/click-app-dir/.click/info/com.test.no-version.manifest (+0/-8) tests/click-app-dir/application.desktop (+0/-6) tests/click-app-dir/chatter.desktop (+0/-9) tests/click-app-dir/noxmir.desktop (+0/-9) tests/click-app-dir/xmir.desktop (+0/-9) tests/click-db-dir/test.conf.in (+0/-2) tests/click-desktop-hook-db/test.conf.in (+0/-2) tests/click-root-dir/com.test.good/1.2.4/.click/info/com.test.good.manifest (+0/-8) tests/click-root-dir/com.test.good/1.2.5/.click/info/com.test.good.manifest (+0/-8) tests/desktop-hook-test.sh.in (+0/-129) tests/helper-handshake-test.cc (+1/-1) tests/helper-test.cc (+3/-42) tests/libertine-service.h (+1/-0) tests/libual-cpp-test.cc (+356/-306) tests/libual-test.cc (+860/-1495) tests/list-apps.cpp (+23/-74) tests/registry-mock.h (+158/-2) tests/snapd-mock.h (+2/-0) tests/spew-master.h (+2/-2) tests/systemd-mock.h (+37/-20) tests/zg-mock.h (+3/-3) ubuntu-app-launch-desktop.click-hook.in (+0/-4) utils/CMakeLists.txt (+7/-0) |
To merge this branch: | bzr merge lp:~ted/ubuntu-app-launch/rm-rf-click |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Pete Woods (community) | Approve | ||
Ken VanDine | Approve | ||
unity-api-1-bot | continuous-integration | Needs Fixing | |
Review via email: mp+318040@code.launchpad.net |
Commit message
Removing support for Click
Description of the change
Removes the Click support but also fixes the tests from helper changes, removing Upstart and finally removing click. The tests should work at the end of this.
unity-api-1-bot (unity-api-1-bot) wrote : | # |
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:326
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:383
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:384
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:387
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:389
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:390
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:391
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Pete Woods (pete-woods) : | # |
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2017-03-21 03:26:39 +0000 |
3 | +++ CMakeLists.txt 2017-03-21 03:26:40 +0000 |
4 | @@ -76,9 +76,6 @@ |
5 | pkg_check_modules(ZEITGEIST REQUIRED zeitgeist-2.0) |
6 | include_directories(${ZEITGEIST_INCLUDE_DIRS}) |
7 | |
8 | -pkg_check_modules(CLICK REQUIRED click-0.4>=0.4.18) |
9 | -include_directories(${CLICK_INCLUDE_DIRS}) |
10 | - |
11 | pkg_check_modules(DBUS REQUIRED dbus-1) |
12 | include_directories(${DBUS_INCLUDE_DIRS}) |
13 | |
14 | @@ -110,36 +107,6 @@ |
15 | add_definitions( -DXMIR_HELPER="${pkglibexecdir}/xmir-helper" ) |
16 | add_definitions( -DSNAPPY_XMIR="${CMAKE_INSTALL_FULL_BINDIR}/snappy-xmir" ) |
17 | |
18 | -#################### |
19 | -# Helpers |
20 | -#################### |
21 | - |
22 | -add_library(helpers STATIC helpers.c helpers-shared.c) |
23 | -target_link_libraries(helpers ${GIO2_LIBRARIES} ${JSONGLIB_LIBRARIES} ${CLICK_LIBRARIES} ${WHOOPSIE_LIBRARIES}) |
24 | - |
25 | -#################### |
26 | -# desktop-hook |
27 | -#################### |
28 | - |
29 | -add_executable(desktop-hook desktop-hook.c) |
30 | -set_target_properties(desktop-hook PROPERTIES OUTPUT_NAME "desktop-hook") |
31 | -target_link_libraries(desktop-hook helpers ${CLICK_LIBRARIES} ${WHOOPSIE_LIBRARIES}) |
32 | -install(TARGETS desktop-hook RUNTIME DESTINATION "${pkglibexecdir}") |
33 | - |
34 | -#################### |
35 | -# oom-adjust-setuid-helper |
36 | -#################### |
37 | - |
38 | -add_executable(oom-adjust-setuid-helper oom-adjust-setuid-helper.c) |
39 | -set_target_properties(oom-adjust-setuid-helper PROPERTIES OUTPUT_NAME "oom-adjust-setuid-helper") |
40 | -install(TARGETS oom-adjust-setuid-helper RUNTIME DESTINATION "${pkglibexecdir}") |
41 | - |
42 | -#################### |
43 | -# ubuntu-app-launch-desktop.click-hook |
44 | -#################### |
45 | - |
46 | -configure_file("ubuntu-app-launch-desktop.click-hook.in" "${CMAKE_CURRENT_SOURCE_DIR}/debian/ubuntu-app-launch-desktop.click-hook" @ONLY) |
47 | - |
48 | add_subdirectory(libubuntu-app-launch) |
49 | add_subdirectory(tools) |
50 | add_subdirectory(ubuntu-app-test) |
51 | |
52 | === modified file 'debian/control' |
53 | --- debian/control 2017-03-21 03:26:39 +0000 |
54 | +++ debian/control 2017-03-21 03:26:40 +0000 |
55 | @@ -3,7 +3,6 @@ |
56 | Priority: optional |
57 | Maintainer: Ted Gould <ted@ubuntu.com> |
58 | Build-Depends: abi-compliance-checker, |
59 | - click-dev (>= 0.2.2), |
60 | cmake, |
61 | cmake-extras (>= 0.10), |
62 | dbus-x11, |
63 | @@ -11,7 +10,6 @@ |
64 | debhelper (>= 9), |
65 | googletest | google-mock, |
66 | libcgmanager-dev, |
67 | - libclick-0.4-dev, |
68 | libcurl4-dev | libcurl4-gnutls-dev, |
69 | libdbus-1-dev, |
70 | libdbustest1-dev (>= 14.04.0), |
71 | @@ -42,7 +40,6 @@ |
72 | Architecture: any |
73 | Depends: ${shlibs:Depends}, |
74 | ${misc:Depends}, |
75 | - click-apparmor, |
76 | dbus-user-session, |
77 | xmir [amd64 armhf i386], |
78 | zeitgeist-core, |
79 | |
80 | === modified file 'debian/rules' |
81 | --- debian/rules 2017-02-15 15:09:13 +0000 |
82 | +++ debian/rules 2017-03-21 03:26:40 +0000 |
83 | @@ -12,10 +12,7 @@ |
84 | export DPKG_GENSYMBOLS_CHECK_LEVEL=4 |
85 | |
86 | %: |
87 | - dh $@ --with click,gir --fail-missing |
88 | - |
89 | -override_dh_click: |
90 | - dh_click --name ubuntu-app-launch-desktop |
91 | + dh $@ --with gir --fail-missing |
92 | |
93 | override_dh_installdeb: |
94 | sed -e"s/#MULTIARCH#/$(DEB_HOST_MULTIARCH)/g" \ |
95 | |
96 | === removed file 'desktop-hook.c' |
97 | --- desktop-hook.c 2016-04-06 16:19:02 +0000 |
98 | +++ desktop-hook.c 1970-01-01 00:00:00 +0000 |
99 | @@ -1,536 +0,0 @@ |
100 | -/* |
101 | - * Copyright 2013 Canonical Ltd. |
102 | - * |
103 | - * This program is free software: you can redistribute it and/or modify it |
104 | - * under the terms of the GNU General Public License version 3, as published |
105 | - * by the Free Software Foundation. |
106 | - * |
107 | - * This program is distributed in the hope that it will be useful, but |
108 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
109 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
110 | - * PURPOSE. See the GNU General Public License for more details. |
111 | - * |
112 | - * You should have received a copy of the GNU General Public License along |
113 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
114 | - * |
115 | - * Authors: |
116 | - * Ted Gould <ted.gould@canonical.com> |
117 | - */ |
118 | - |
119 | -/* |
120 | - |
121 | -INTRODUCTION: |
122 | - |
123 | -This is a hook for Click packages. You can find information on Click package hooks in |
124 | -the click documentation: |
125 | - |
126 | -https://click.readthedocs.org/en/latest/ |
127 | - |
128 | -Probably the biggest thing to understand for how this code works is that you need to |
129 | -understand that this hook is run after one, or many packages are installed. A set of |
130 | -symbolic links are made to the desktop files per-application (not per-package) in the |
131 | -directory specified in ubuntu-app-launcher-desktop.click-hook.in. Those desktop files |
132 | -give us the App ID of the packages that are installed and have applications needing |
133 | -desktop files in them. We then operate on each of them ensuring that they are synchronized |
134 | -with the desktop files in ~/.local/share/applications/. |
135 | - |
136 | -The desktop files that we're creating there ARE NOT used for execution by the |
137 | -ubuntu-app-launch Upstart jobs. They are there so that Unity can know which applications |
138 | -are installed for this user and they provide an Exec line to allow compatibility with |
139 | -desktop environments that are not using ubuntu-app-launch for launching applications. |
140 | -You should not modify them and expect any executing under Unity to change. |
141 | - |
142 | -*/ |
143 | - |
144 | -#include <gio/gio.h> |
145 | -#include <glib/gstdio.h> |
146 | -#include <click.h> |
147 | -#include <string.h> |
148 | -#include <errno.h> |
149 | -#include <libwhoopsie/recoverable-problem.h> |
150 | - |
151 | -#include "helpers.h" |
152 | - |
153 | -typedef struct _app_state_t app_state_t; |
154 | -struct _app_state_t { |
155 | - gchar * app_id; |
156 | - gboolean has_click; |
157 | - gboolean has_desktop; |
158 | - guint64 click_modified; |
159 | - guint64 desktop_modified; |
160 | -}; |
161 | - |
162 | -/* Desktop Group */ |
163 | -#define DESKTOP_GROUP "Desktop Entry" |
164 | -/* Desktop Keys */ |
165 | -#define APP_ID_KEY "X-Ubuntu-Application-ID" |
166 | -#define PATH_KEY "Path" |
167 | -#define EXEC_KEY "Exec" |
168 | -#define ICON_KEY "Icon" |
169 | -#define SYMBOLIC_ICON_KEY "X-Ubuntu-SymbolicIcon" |
170 | -#define SOURCE_FILE_KEY "X-Ubuntu-UAL-Source-Desktop" |
171 | -/* Other */ |
172 | -#define OLD_KEY_PREFIX "X-Ubuntu-Old-" |
173 | - |
174 | -/* Find an entry in the app array */ |
175 | -app_state_t * |
176 | -find_app_entry (const gchar * name, GArray * app_array) |
177 | -{ |
178 | - int i; |
179 | - for (i = 0; i < app_array->len; i++) { |
180 | - app_state_t * state = &g_array_index(app_array, app_state_t, i); |
181 | - |
182 | - if (g_strcmp0(state->app_id, name) == 0) { |
183 | - return state; |
184 | - } |
185 | - } |
186 | - |
187 | - app_state_t newstate; |
188 | - newstate.has_click = FALSE; |
189 | - newstate.has_desktop = FALSE; |
190 | - newstate.click_modified = 0; |
191 | - newstate.desktop_modified = 0; |
192 | - newstate.app_id = g_strdup(name); |
193 | - |
194 | - g_array_append_val(app_array, newstate); |
195 | - |
196 | - /* Note: The pointer needs to be the entry in the array, not the |
197 | - one that we have on the stack. Criticaly important. */ |
198 | - app_state_t * statepntr = &g_array_index(app_array, app_state_t, app_array->len - 1); |
199 | - return statepntr; |
200 | -} |
201 | - |
202 | -/* Looks up the file creation time, which seems harder with GLib |
203 | - than it should be */ |
204 | -guint64 |
205 | -modified_time (const gchar * dir, const gchar * filename) |
206 | -{ |
207 | - gchar * path = g_build_filename(dir, filename, NULL); |
208 | - GFile * file = g_file_new_for_path(path); |
209 | - GFileInfo * info = g_file_query_info(file, G_FILE_ATTRIBUTE_TIME_MODIFIED, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); |
210 | - |
211 | - guint64 time = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED); |
212 | - |
213 | - g_object_unref(info); |
214 | - g_object_unref(file); |
215 | - g_free(path); |
216 | - |
217 | - return time; |
218 | -} |
219 | - |
220 | -/* Look at an click package entry */ |
221 | -void |
222 | -add_click_package (const gchar * dir, const gchar * name, GArray * app_array) |
223 | -{ |
224 | - if (!g_str_has_suffix(name, ".desktop")) { |
225 | - return; |
226 | - } |
227 | - |
228 | - gchar * appid = g_strdup(name); |
229 | - g_strstr_len(appid, -1, ".desktop")[0] = '\0'; |
230 | - |
231 | - app_state_t * state = find_app_entry(appid, app_array); |
232 | - state->has_click = TRUE; |
233 | - state->click_modified = modified_time(dir, name); |
234 | - |
235 | - g_free(appid); |
236 | - |
237 | - return; |
238 | -} |
239 | - |
240 | -/* Look at the desktop file and ensure that it was built by us, and if it |
241 | - was that its source still exists */ |
242 | -gboolean |
243 | -desktop_source_exists (const gchar * dir, const gchar * name) |
244 | -{ |
245 | - gchar * desktopfile = g_build_filename(dir, name, NULL); |
246 | - |
247 | - GKeyFile * keyfile = g_key_file_new(); |
248 | - g_key_file_load_from_file(keyfile, |
249 | - desktopfile, |
250 | - G_KEY_FILE_NONE, |
251 | - NULL); /* No error */ |
252 | - |
253 | - if (!g_key_file_has_key(keyfile, DESKTOP_GROUP, SOURCE_FILE_KEY, NULL)) { |
254 | - gboolean hasappid = g_key_file_has_key(keyfile, DESKTOP_GROUP, APP_ID_KEY, NULL); |
255 | - g_free(desktopfile); |
256 | - g_key_file_free(keyfile); |
257 | - return hasappid; |
258 | - } |
259 | - |
260 | - /* At this point we know the key exists, so if we can't find the source |
261 | - file we want to delete the file as well. We need to replace it. */ |
262 | - gchar * originalfile = g_key_file_get_string(keyfile, DESKTOP_GROUP, SOURCE_FILE_KEY, NULL); |
263 | - g_key_file_free(keyfile); |
264 | - gboolean found = TRUE; |
265 | - |
266 | - if (!g_file_test(originalfile, G_FILE_TEST_EXISTS)) { |
267 | - g_remove(desktopfile); |
268 | - found = FALSE; |
269 | - } |
270 | - |
271 | - g_free(originalfile); |
272 | - g_free(desktopfile); |
273 | - |
274 | - return found; |
275 | -} |
276 | - |
277 | -/* Look at an desktop file entry */ |
278 | -void |
279 | -add_desktop_file (const gchar * dir, const gchar * name, GArray * app_array) |
280 | -{ |
281 | - if (!g_str_has_suffix(name, ".desktop")) { |
282 | - return; |
283 | - } |
284 | - |
285 | - if (!desktop_source_exists(dir, name)) { |
286 | - return; |
287 | - } |
288 | - |
289 | - gchar * appid = g_strdup(name); |
290 | - g_strstr_len(appid, -1, ".desktop")[0] = '\0'; |
291 | - |
292 | - /* We only want valid APP IDs as desktop files */ |
293 | - if (!app_id_to_triplet(appid, NULL, NULL, NULL)) { |
294 | - g_free(appid); |
295 | - return; |
296 | - } |
297 | - |
298 | - app_state_t * state = find_app_entry(appid, app_array); |
299 | - state->has_desktop = TRUE; |
300 | - state->desktop_modified = modified_time(dir, name); |
301 | - |
302 | - g_free(appid); |
303 | - return; |
304 | -} |
305 | - |
306 | -/* Open a directory and look at all the entries */ |
307 | -void |
308 | -dir_for_each (const gchar * dirname, void(*func)(const gchar * dir, const gchar * name, GArray * app_array), GArray * app_array) |
309 | -{ |
310 | - GError * error = NULL; |
311 | - GDir * directory = g_dir_open(dirname, 0, &error); |
312 | - |
313 | - if (error != NULL) { |
314 | - g_warning("Unable to read directory '%s': %s", dirname, error->message); |
315 | - g_error_free(error); |
316 | - return; |
317 | - } |
318 | - |
319 | - const gchar * filename = NULL; |
320 | - while ((filename = g_dir_read_name(directory)) != NULL) { |
321 | - func(dirname, filename, app_array); |
322 | - } |
323 | - |
324 | - g_dir_close(directory); |
325 | - return; |
326 | -} |
327 | - |
328 | -/* Code to report an error, so we can start tracking how important this is */ |
329 | -static void |
330 | -report_recoverable_error (const gchar * app_id, const gchar * iconfield, const gchar * originalicon, const gchar * iconpath) |
331 | -{ |
332 | - const char * properties[9] = { |
333 | - "IconValue", NULL, |
334 | - "AppID", NULL, |
335 | - "IconPath", NULL, |
336 | - "IconField", NULL, |
337 | - NULL |
338 | - }; |
339 | - |
340 | - properties[1] = originalicon; |
341 | - properties[3] = app_id; |
342 | - properties[5] = iconpath; |
343 | - properties[7] = iconfield; |
344 | - |
345 | - whoopsie_report_recoverable_problem("icon-path-unhandled", 0, TRUE, properties); |
346 | - |
347 | - return; |
348 | -} |
349 | - |
350 | -/* Function to take the source Desktop file and build a new |
351 | - one with similar, but not the same data in it */ |
352 | -static void |
353 | -copy_desktop_file (const gchar * from, const gchar * to, const gchar * appdir, const gchar * app_id) |
354 | -{ |
355 | - GError * error = NULL; |
356 | - GKeyFile * keyfile = g_key_file_new(); |
357 | - g_key_file_load_from_file(keyfile, |
358 | - from, |
359 | - G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, |
360 | - &error); |
361 | - |
362 | - if (error != NULL) { |
363 | - g_warning("Unable to read the desktop file '%s' in the application directory: %s", from, error->message); |
364 | - g_error_free(error); |
365 | - g_key_file_unref(keyfile); |
366 | - return; |
367 | - } |
368 | - |
369 | - /* Path Hanlding */ |
370 | - if (g_key_file_has_key(keyfile, DESKTOP_GROUP, PATH_KEY, NULL)) { |
371 | - gchar * oldpath = g_key_file_get_string(keyfile, DESKTOP_GROUP, PATH_KEY, NULL); |
372 | - g_debug("Desktop file '%s' has a Path set to '%s'. Setting as " OLD_KEY_PREFIX PATH_KEY ".", from, oldpath); |
373 | - |
374 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, OLD_KEY_PREFIX PATH_KEY, oldpath); |
375 | - |
376 | - g_free(oldpath); |
377 | - } |
378 | - |
379 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, PATH_KEY, appdir); |
380 | - |
381 | - /* Icon Handling */ |
382 | - if (g_key_file_has_key(keyfile, DESKTOP_GROUP, ICON_KEY, NULL)) { |
383 | - gchar * originalicon = g_key_file_get_string(keyfile, DESKTOP_GROUP, ICON_KEY, NULL); |
384 | - gchar * iconpath = g_build_filename(appdir, originalicon, NULL); |
385 | - |
386 | - /* If the icon in the path exists, let's use that */ |
387 | - if (g_file_test(iconpath, G_FILE_TEST_EXISTS)) { |
388 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, ICON_KEY, iconpath); |
389 | - /* Save the old value, because, debugging */ |
390 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, OLD_KEY_PREFIX ICON_KEY, originalicon); |
391 | - } else { |
392 | - /* So here we are, realizing all is lost. Let's file a bug. */ |
393 | - /* The goal here is to realize how often this case is, so we know how to prioritize fixing it */ |
394 | - |
395 | - report_recoverable_error(app_id, ICON_KEY, originalicon, iconpath); |
396 | - } |
397 | - |
398 | - g_free(iconpath); |
399 | - g_free(originalicon); |
400 | - } |
401 | - |
402 | - /* SymbolicIcon Handling */ |
403 | - if (g_key_file_has_key(keyfile, DESKTOP_GROUP, SYMBOLIC_ICON_KEY, NULL)) { |
404 | - gchar * originalicon = g_key_file_get_string(keyfile, DESKTOP_GROUP, SYMBOLIC_ICON_KEY, NULL); |
405 | - gchar * iconpath = g_build_filename(appdir, originalicon, NULL); |
406 | - |
407 | - /* If the icon in the path exists, let's use that */ |
408 | - if (g_file_test(iconpath, G_FILE_TEST_EXISTS)) { |
409 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, SYMBOLIC_ICON_KEY, iconpath); |
410 | - /* Save the old value, because, debugging */ |
411 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, OLD_KEY_PREFIX SYMBOLIC_ICON_KEY, originalicon); |
412 | - } else { |
413 | - /* So here we are, realizing all is lost. Let's file a bug. */ |
414 | - /* The goal here is to realize how often this case is, so we know how to prioritize fixing it */ |
415 | - |
416 | - report_recoverable_error(app_id, SYMBOLIC_ICON_KEY, originalicon, iconpath); |
417 | - } |
418 | - |
419 | - g_free(iconpath); |
420 | - g_free(originalicon); |
421 | - } |
422 | - |
423 | - /* Exec Handling */ |
424 | - gchar * oldexec = desktop_to_exec(keyfile, from); |
425 | - if (oldexec == NULL) { |
426 | - g_key_file_unref(keyfile); |
427 | - return; |
428 | - } |
429 | - |
430 | - gchar * newexec = g_strdup_printf("aa-exec-click -p %s -- %s", app_id, oldexec); |
431 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, EXEC_KEY, newexec); |
432 | - g_free(newexec); |
433 | - g_free(oldexec); |
434 | - |
435 | - /* Adding an Application ID */ |
436 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, APP_ID_KEY, app_id); |
437 | - |
438 | - /* Adding the source file path */ |
439 | - g_key_file_set_string(keyfile, DESKTOP_GROUP, SOURCE_FILE_KEY, from); |
440 | - |
441 | - /* Output */ |
442 | - gsize datalen = 0; |
443 | - gchar * data = g_key_file_to_data(keyfile, &datalen, &error); |
444 | - g_key_file_unref(keyfile); |
445 | - |
446 | - if (error != NULL) { |
447 | - g_warning("Unable serialize keyfile built from '%s': %s", from, error->message); |
448 | - g_error_free(error); |
449 | - return; |
450 | - } |
451 | - |
452 | - g_file_set_contents(to, data, datalen, &error); |
453 | - g_free(data); |
454 | - |
455 | - if (error != NULL) { |
456 | - g_warning("Unable to write out desktop file to '%s': %s", to, error->message); |
457 | - g_error_free(error); |
458 | - return; |
459 | - } |
460 | - |
461 | - return; |
462 | -} |
463 | - |
464 | -/* Build a desktop file in the user's home directory */ |
465 | -static void |
466 | -build_desktop_file (app_state_t * state, const gchar * symlinkdir, const gchar * desktopdir) |
467 | -{ |
468 | - GError * error = NULL; |
469 | - gchar * package = NULL; |
470 | - /* 'Parse' the App ID */ |
471 | - if (!app_id_to_triplet(state->app_id, &package, NULL, NULL)) { |
472 | - return; |
473 | - } |
474 | - |
475 | - /* Read in the database */ |
476 | - ClickDB * db = click_db_new(); |
477 | - click_db_read(db, g_getenv("TEST_CLICK_DB"), &error); |
478 | - if (error != NULL) { |
479 | - g_warning("Unable to read Click database: %s", error->message); |
480 | - g_error_free(error); |
481 | - g_free(package); |
482 | - g_object_unref(db); |
483 | - return; |
484 | - } |
485 | - |
486 | - /* Check click to find out where the files are */ |
487 | - ClickUser * user = click_user_new_for_user(db, g_getenv("TEST_CLICK_USER"), &error); |
488 | - g_object_unref(db); |
489 | - if (error != NULL) { |
490 | - g_warning("Unable to read Click database: %s", error->message); |
491 | - g_error_free(error); |
492 | - g_free(package); |
493 | - return; |
494 | - } |
495 | - |
496 | - gchar * pkgdir = click_user_get_path(user, package, &error); |
497 | - if (error != NULL) { |
498 | - g_warning("Unable to get the Click package directory for %s: %s", package, error->message); |
499 | - g_error_free(error); |
500 | - g_free(package); |
501 | - return; |
502 | - } |
503 | - g_object_unref(user); |
504 | - g_free(package); |
505 | - |
506 | - if (!g_file_test(pkgdir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { |
507 | - g_warning("Directory returned by click '%s' couldn't be found", pkgdir); |
508 | - g_free(pkgdir); |
509 | - return; |
510 | - } |
511 | - |
512 | - gchar * indesktop = manifest_to_desktop(pkgdir, state->app_id); |
513 | - if (indesktop == NULL) { |
514 | - g_free(pkgdir); |
515 | - return; |
516 | - } |
517 | - |
518 | - /* Determine the desktop file name */ |
519 | - gchar * desktopfile = g_strdup_printf("%s.desktop", state->app_id); |
520 | - gchar * desktoppath = g_build_filename(desktopdir, desktopfile, NULL); |
521 | - g_free(desktopfile); |
522 | - |
523 | - copy_desktop_file(indesktop, desktoppath, pkgdir, state->app_id); |
524 | - |
525 | - g_free(desktoppath); |
526 | - g_free(indesktop); |
527 | - g_free(pkgdir); |
528 | - |
529 | - return; |
530 | -} |
531 | - |
532 | -/* Remove the desktop file from the user's home directory */ |
533 | -static gboolean |
534 | -remove_desktop_file (app_state_t * state, const gchar * desktopdir) |
535 | -{ |
536 | - gchar * desktopfile = g_strdup_printf("%s.desktop", state->app_id); |
537 | - gchar * desktoppath = g_build_filename(desktopdir, desktopfile, NULL); |
538 | - g_free(desktopfile); |
539 | - |
540 | - GKeyFile * keyfile = g_key_file_new(); |
541 | - g_key_file_load_from_file(keyfile, |
542 | - desktoppath, |
543 | - G_KEY_FILE_NONE, |
544 | - NULL); |
545 | - |
546 | - if (!g_key_file_has_key(keyfile, DESKTOP_GROUP, APP_ID_KEY, NULL)) { |
547 | - g_debug("Desktop file '%s' is not one created by us.", desktoppath); |
548 | - g_key_file_unref(keyfile); |
549 | - g_free(desktoppath); |
550 | - return FALSE; |
551 | - } |
552 | - g_key_file_unref(keyfile); |
553 | - |
554 | - if (g_unlink(desktoppath) != 0) { |
555 | - g_warning("Unable to delete desktop file: %s", desktoppath); |
556 | - } |
557 | - |
558 | - g_free(desktoppath); |
559 | - |
560 | - return TRUE; |
561 | -} |
562 | - |
563 | -/* The main function */ |
564 | -int |
565 | -main (int argc, char * argv[]) |
566 | -{ |
567 | - if (argc != 1) { |
568 | - g_error("Shouldn't have arguments"); |
569 | - return 1; |
570 | - } |
571 | - |
572 | - GArray * apparray = g_array_new(FALSE, FALSE, sizeof(app_state_t)); |
573 | - |
574 | - /* Find all the symlinks of desktop files */ |
575 | - gchar * symlinkdir = g_build_filename(g_get_user_cache_dir(), "ubuntu-app-launch", "desktop", NULL); |
576 | - if (!g_file_test(symlinkdir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { |
577 | - g_debug("No installed click packages"); |
578 | - } else { |
579 | - dir_for_each(symlinkdir, add_click_package, apparray); |
580 | - } |
581 | - |
582 | - /* Find all the click desktop files */ |
583 | - gchar * desktopdir = g_build_filename(g_get_user_data_dir(), "applications", NULL); |
584 | - gboolean desktopdirexists = FALSE; |
585 | - if (!g_file_test(desktopdir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { |
586 | - g_debug("No applications defined"); |
587 | - } else { |
588 | - dir_for_each(desktopdir, add_desktop_file, apparray); |
589 | - desktopdirexists = TRUE; |
590 | - } |
591 | - |
592 | - /* Process the merge */ |
593 | - int i; |
594 | - for (i = 0; i < apparray->len; i++) { |
595 | - app_state_t * state = &g_array_index(apparray, app_state_t, i); |
596 | - g_debug("Processing App ID: %s", state->app_id); |
597 | - |
598 | - if (state->has_click && state->has_desktop) { |
599 | - if (state->click_modified > state->desktop_modified) { |
600 | - g_debug("\tClick updated more recently"); |
601 | - g_debug("\tRemoving desktop file"); |
602 | - if (remove_desktop_file(state, desktopdir)) { |
603 | - g_debug("\tBuilding desktop file"); |
604 | - build_desktop_file(state, symlinkdir, desktopdir); |
605 | - } |
606 | - } else { |
607 | - g_debug("\tAlready synchronized"); |
608 | - } |
609 | - } else if (state->has_click) { |
610 | - if (!desktopdirexists) { |
611 | - if (g_mkdir_with_parents(desktopdir, 0755) == 0) { |
612 | - g_debug("\tCreated applications directory"); |
613 | - desktopdirexists = TRUE; |
614 | - } else { |
615 | - g_warning("\tUnable to create applications directory"); |
616 | - } |
617 | - } |
618 | - if (desktopdirexists) { |
619 | - g_debug("\tBuilding desktop file"); |
620 | - build_desktop_file(state, symlinkdir, desktopdir); |
621 | - } |
622 | - } else if (state->has_desktop) { |
623 | - g_debug("\tRemoving desktop file"); |
624 | - remove_desktop_file(state, desktopdir); |
625 | - } |
626 | - |
627 | - g_free(state->app_id); |
628 | - } |
629 | - |
630 | - g_array_free(apparray, TRUE); |
631 | - g_free(desktopdir); |
632 | - g_free(symlinkdir); |
633 | - |
634 | - return 0; |
635 | -} |
636 | |
637 | === modified file 'docs/index.rst' |
638 | --- docs/index.rst 2017-03-21 03:26:39 +0000 |
639 | +++ docs/index.rst 2017-03-21 03:26:40 +0000 |
640 | @@ -37,9 +37,6 @@ |
641 | UBUNTU_APP_LAUNCH_LIBERTINE_LAUNCH |
642 | Path to the libertine launch utility for setting up libertine containers and XMir based legacy apps. |
643 | |
644 | -UBUNTU_APP_LAUNCH_LINK_FARM |
645 | - Path to the link farm that is created by Click of all the installed Click applications. |
646 | - |
647 | UBUNTU_APP_LAUNCH_OOM_HELPER |
648 | Path to the setuid helper that configures OOM values on application processes that we otherwise couldn't, mostly this is for Oxide. |
649 | |
650 | @@ -119,16 +116,6 @@ |
651 | :private-members: |
652 | :undoc-members: |
653 | |
654 | -Application Implementation Click |
655 | --------------------------------- |
656 | - |
657 | -.. doxygenclass:: ubuntu::app_launch::app_impls::Click |
658 | - :project: libubuntu-app-launch |
659 | - :members: |
660 | - :protected-members: |
661 | - :private-members: |
662 | - :undoc-members: |
663 | - |
664 | Application Implementation Legacy |
665 | --------------------------------- |
666 | |
667 | @@ -199,16 +186,6 @@ |
668 | :private-members: |
669 | :undoc-members: |
670 | |
671 | -Application Storage Click |
672 | -------------------------- |
673 | - |
674 | -.. doxygenclass:: ubuntu::app_launch::app_store::Click |
675 | - :project: libubuntu-app-launch |
676 | - :members: |
677 | - :protected-members: |
678 | - :private-members: |
679 | - :undoc-members: |
680 | - |
681 | Application Storage Legacy |
682 | -------------------------- |
683 | |
684 | |
685 | === modified file 'libubuntu-app-launch/CMakeLists.txt' |
686 | --- libubuntu-app-launch/CMakeLists.txt 2017-03-21 03:26:39 +0000 |
687 | +++ libubuntu-app-launch/CMakeLists.txt 2017-03-21 03:26:40 +0000 |
688 | @@ -39,8 +39,6 @@ |
689 | application.cpp |
690 | app-store-base.h |
691 | app-store-base.cpp |
692 | -app-store-click.h |
693 | -app-store-click.cpp |
694 | app-store-legacy.h |
695 | app-store-legacy.cpp |
696 | app-store-libertine.h |
697 | @@ -54,12 +52,12 @@ |
698 | registry-impl.cpp |
699 | application-impl-base.h |
700 | application-impl-base.cpp |
701 | -application-impl-click.h |
702 | -application-impl-click.cpp |
703 | application-impl-legacy.h |
704 | application-impl-legacy.cpp |
705 | application-impl-libertine.h |
706 | application-impl-libertine.cpp |
707 | +application-impl-snap.h |
708 | +application-impl-snap.cpp |
709 | application-info-desktop.h |
710 | application-info-desktop.cpp |
711 | application-icon-finder.h |
712 | @@ -74,24 +72,17 @@ |
713 | jobs-base.cpp |
714 | jobs-systemd.h |
715 | jobs-systemd.cpp |
716 | +snapd-info.h |
717 | +snapd-info.cpp |
718 | ) |
719 | |
720 | set(LAUNCHER_SOURCES |
721 | ubuntu-app-launch.cpp |
722 | second-exec-core.c |
723 | ubuntu-app-launch-trace.c |
724 | -app-info.c |
725 | -) |
726 | - |
727 | -if(CURL_FOUND) |
728 | -add_definitions ( -DENABLE_SNAPPY=1 ) |
729 | -list(APPEND LAUNCHER_CPP_SOURCES |
730 | -application-impl-snap.h |
731 | -application-impl-snap.cpp |
732 | -snapd-info.h |
733 | -snapd-info.cpp |
734 | -) |
735 | -endif() |
736 | +utils.c |
737 | +utils-shared.c |
738 | +) |
739 | |
740 | add_custom_target(format |
741 | COMMAND clang-format -i -style=file ${LAUNCHER_CPP_HEADERS} ${LAUNCHER_CPP_SOURCES} |
742 | @@ -117,7 +108,6 @@ |
743 | ${LIBERTINE_LIBRARIES} |
744 | ${CURL_LIBRARIES} |
745 | -lpthread |
746 | - helpers |
747 | -Wl,--no-undefined |
748 | ) |
749 | |
750 | @@ -144,7 +134,6 @@ |
751 | ${LIBERTINE_LIBRARIES} |
752 | ${CURL_LIBRARIES} |
753 | -lpthread |
754 | - helpers |
755 | -Wl,--no-undefined |
756 | ) |
757 | |
758 | |
759 | === removed file 'libubuntu-app-launch/app-info.c' |
760 | --- libubuntu-app-launch/app-info.c 2016-08-24 20:29:25 +0000 |
761 | +++ libubuntu-app-launch/app-info.c 1970-01-01 00:00:00 +0000 |
762 | @@ -1,277 +0,0 @@ |
763 | -/* |
764 | - * Copyright © 2015 Canonical Ltd. |
765 | - * |
766 | - * This program is free software: you can redistribute it and/or modify it |
767 | - * under the terms of the GNU General Public License version 3, as published |
768 | - * by the Free Software Foundation. |
769 | - * |
770 | - * This program is distributed in the hope that it will be useful, but |
771 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
772 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
773 | - * PURPOSE. See the GNU General Public License for more details. |
774 | - * |
775 | - * You should have received a copy of the GNU General Public License along |
776 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
777 | - * |
778 | - * Authors: |
779 | - * Ted Gould <ted.gould@canonical.com> |
780 | - */ |
781 | - |
782 | -#include <json-glib/json-glib.h> |
783 | -#include <click.h> |
784 | - |
785 | -#include "ubuntu-app-launch.h" |
786 | - |
787 | -/* Prototypes */ |
788 | -static gboolean app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop); |
789 | - |
790 | -/* Try and get a manifest and do a couple sanity checks on it */ |
791 | -static JsonObject * |
792 | -get_manifest (const gchar * pkg, gchar ** pkgpath) |
793 | -{ |
794 | - /* Get the directory from click */ |
795 | - GError * error = NULL; |
796 | - |
797 | - ClickDB * db = click_db_new(); |
798 | - /* If TEST_CLICK_DB is unset, this reads the system database. */ |
799 | - click_db_read(db, g_getenv("TEST_CLICK_DB"), &error); |
800 | - if (error != NULL) { |
801 | - g_warning("Unable to read Click database: %s", error->message); |
802 | - g_error_free(error); |
803 | - g_object_unref(db); |
804 | - return NULL; |
805 | - } |
806 | - /* If TEST_CLICK_USER is unset, this uses the current user name. */ |
807 | - ClickUser * user = click_user_new_for_user(db, g_getenv("TEST_CLICK_USER"), &error); |
808 | - if (error != NULL) { |
809 | - g_warning("Unable to read Click database: %s", error->message); |
810 | - g_error_free(error); |
811 | - g_object_unref(db); |
812 | - return NULL; |
813 | - } |
814 | - g_object_unref(db); |
815 | - JsonObject * manifest = click_user_get_manifest(user, pkg, &error); |
816 | - if (error != NULL) { |
817 | - g_warning("Unable to get manifest for '%s' package: %s", pkg, error->message); |
818 | - g_error_free(error); |
819 | - g_object_unref(user); |
820 | - return NULL; |
821 | - } |
822 | - |
823 | - if (pkgpath != NULL) { |
824 | - *pkgpath = click_user_get_path(user, pkg, &error); |
825 | - if (error != NULL) { |
826 | - g_warning("Unable to get the Click package directory for %s: %s", pkg, error->message); |
827 | - g_error_free(error); |
828 | - g_object_unref(user); |
829 | - return NULL; |
830 | - } |
831 | - } |
832 | - g_object_unref(user); |
833 | - |
834 | - if (!json_object_has_member(manifest, "version")) { |
835 | - g_warning("Manifest file for package '%s' does not have a version", pkg); |
836 | - json_object_unref(manifest); |
837 | - return NULL; |
838 | - } |
839 | - |
840 | - return manifest; |
841 | -} |
842 | - |
843 | -/* Look to see if the app id results in a desktop file, if so, fill in the params */ |
844 | -static gboolean |
845 | -evaluate_dir (const gchar * dir, const gchar * desktop, gchar ** appdir, gchar ** appdesktop) |
846 | -{ |
847 | - char * fulldir = g_build_filename(dir, "applications", desktop, NULL); |
848 | - gboolean found = FALSE; |
849 | - |
850 | - if (g_file_test(fulldir, G_FILE_TEST_EXISTS)) { |
851 | - if (appdir != NULL) { |
852 | - *appdir = g_strdup(dir); |
853 | - } |
854 | - |
855 | - if (appdesktop != NULL) { |
856 | - *appdesktop = g_strdup_printf("applications/%s", desktop); |
857 | - } |
858 | - |
859 | - found = TRUE; |
860 | - } |
861 | - |
862 | - g_free(fulldir); |
863 | - return found; |
864 | -} |
865 | - |
866 | -/* Handle the legacy case where we look through the data directories */ |
867 | -static gboolean |
868 | -app_info_legacy (const gchar * appid, gchar ** appdir, gchar ** appdesktop) |
869 | -{ |
870 | - gchar * desktop = g_strdup_printf("%s.desktop", appid); |
871 | - |
872 | - /* Special case the user's dir */ |
873 | - if (evaluate_dir(g_get_user_data_dir(), desktop, appdir, appdesktop)) { |
874 | - g_free(desktop); |
875 | - return TRUE; |
876 | - } |
877 | - |
878 | - const char * const * data_dirs = g_get_system_data_dirs(); |
879 | - int i; |
880 | - for (i = 0; data_dirs[i] != NULL; i++) { |
881 | - if (evaluate_dir(data_dirs[i], desktop, appdir, appdesktop)) { |
882 | - g_free(desktop); |
883 | - return TRUE; |
884 | - } |
885 | - } |
886 | - |
887 | - return FALSE; |
888 | -} |
889 | - |
890 | -/* Handle the libertine case where we look in the container */ |
891 | -static gboolean |
892 | -app_info_libertine (const gchar * appid, gchar ** appdir, gchar ** appdesktop) |
893 | -{ |
894 | - char * container = NULL; |
895 | - char * app = NULL; |
896 | - |
897 | - if (!ubuntu_app_launch_app_id_parse(appid, &container, &app, NULL)) { |
898 | - return FALSE; |
899 | - } |
900 | - |
901 | - gchar * desktopname = g_strdup_printf("%s.desktop", app); |
902 | - |
903 | - gchar * desktopdir = g_build_filename(g_get_user_cache_dir(), "libertine-container", container, "rootfs", "usr", "share", NULL); |
904 | - gchar * desktopfile = g_build_filename(desktopdir, "applications", desktopname, NULL); |
905 | - |
906 | - if (!g_file_test(desktopfile, G_FILE_TEST_EXISTS)) { |
907 | - g_free(desktopdir); |
908 | - g_free(desktopfile); |
909 | - |
910 | - desktopdir = g_build_filename(g_get_user_data_dir(), "libertine-container", "user-data", container, ".local", "share", NULL); |
911 | - desktopfile = g_build_filename(desktopdir, "applications", desktopname, NULL); |
912 | - |
913 | - if (!g_file_test(desktopfile, G_FILE_TEST_EXISTS)) { |
914 | - g_free(desktopdir); |
915 | - g_free(desktopfile); |
916 | - |
917 | - g_free(desktopname); |
918 | - g_free(container); |
919 | - g_free(app); |
920 | - |
921 | - return FALSE; |
922 | - } |
923 | - } |
924 | - |
925 | - if (appdir != NULL) { |
926 | - *appdir = desktopdir; |
927 | - } else { |
928 | - g_free(desktopdir); |
929 | - } |
930 | - |
931 | - if (appdesktop != NULL) { |
932 | - *appdesktop = g_build_filename("applications", desktopname, NULL); |
933 | - } |
934 | - |
935 | - g_free(desktopfile); |
936 | - g_free(desktopname); |
937 | - g_free(container); |
938 | - g_free(app); |
939 | - |
940 | - return TRUE; |
941 | -} |
942 | - |
943 | -/* Get the information on where the desktop file is from libclick */ |
944 | -static gboolean |
945 | -app_info_click (const gchar * appid, gchar ** appdir, gchar ** appdesktop) |
946 | -{ |
947 | - gchar * package = NULL; |
948 | - gchar * application = NULL; |
949 | - |
950 | - if (!ubuntu_app_launch_app_id_parse(appid, &package, &application, NULL)) { |
951 | - return FALSE; |
952 | - } |
953 | - |
954 | - JsonObject * manifest = get_manifest(package, appdir); |
955 | - if (manifest == NULL) { |
956 | - g_free(package); |
957 | - g_free(application); |
958 | - return FALSE; |
959 | - } |
960 | - |
961 | - g_free(package); |
962 | - |
963 | - if (appdesktop != NULL) { |
964 | - JsonObject * hooks = json_object_get_object_member(manifest, "hooks"); |
965 | - if (hooks == NULL) { |
966 | - json_object_unref(manifest); |
967 | - g_free(application); |
968 | - return FALSE; |
969 | - } |
970 | - |
971 | - JsonObject * appobj = json_object_get_object_member(hooks, application); |
972 | - g_free(application); |
973 | - |
974 | - if (appobj == NULL) { |
975 | - json_object_unref(manifest); |
976 | - return FALSE; |
977 | - } |
978 | - |
979 | - const gchar * desktop = json_object_get_string_member(appobj, "desktop"); |
980 | - if (desktop == NULL) { |
981 | - json_object_unref(manifest); |
982 | - return FALSE; |
983 | - } |
984 | - |
985 | - *appdesktop = g_strdup(desktop); |
986 | - } else { |
987 | - g_free(application); |
988 | - } |
989 | - |
990 | - json_object_unref(manifest); |
991 | - |
992 | - return TRUE; |
993 | -} |
994 | - |
995 | -/* Determine whether it's a click package by looking for the symlink |
996 | - that is created by the desktop hook */ |
997 | -static gboolean |
998 | -is_click (const gchar * appid) |
999 | -{ |
1000 | - gchar * appiddesktop = g_strdup_printf("%s.desktop", appid); |
1001 | - gchar * click_link = NULL; |
1002 | - const gchar * link_farm_dir = g_getenv("UBUNTU_APP_LAUNCH_LINK_FARM"); |
1003 | - if (G_LIKELY(link_farm_dir == NULL)) { |
1004 | - click_link = g_build_filename(g_get_user_cache_dir(), "ubuntu-app-launch", "desktop", appiddesktop, NULL); |
1005 | - } else { |
1006 | - click_link = g_build_filename(link_farm_dir, appiddesktop, NULL); |
1007 | - } |
1008 | - g_free(appiddesktop); |
1009 | - gboolean click = g_file_test(click_link, G_FILE_TEST_EXISTS); |
1010 | - g_free(click_link); |
1011 | - |
1012 | - return click; |
1013 | -} |
1014 | - |
1015 | -/* Determine whether an AppId is realated to a Libertine container by |
1016 | - checking the container and program name. */ |
1017 | -static gboolean |
1018 | -is_libertine (const gchar * appid) |
1019 | -{ |
1020 | - if (app_info_libertine(appid, NULL, NULL)) { |
1021 | - g_debug("Libertine application detected: %s", appid); |
1022 | - return TRUE; |
1023 | - } else { |
1024 | - return FALSE; |
1025 | - } |
1026 | -} |
1027 | - |
1028 | -gboolean |
1029 | -ubuntu_app_launch_application_info (const gchar * appid, gchar ** appdir, gchar ** appdesktop) |
1030 | -{ |
1031 | - if (is_click(appid)) { |
1032 | - return app_info_click(appid, appdir, appdesktop); |
1033 | - } else if (is_libertine(appid)) { |
1034 | - return app_info_libertine(appid, appdir, appdesktop); |
1035 | - } else { |
1036 | - return app_info_legacy(appid, appdir, appdesktop); |
1037 | - } |
1038 | -} |
1039 | - |
1040 | |
1041 | === modified file 'libubuntu-app-launch/app-store-base.cpp' |
1042 | --- libubuntu-app-launch/app-store-base.cpp 2017-03-21 03:26:39 +0000 |
1043 | +++ libubuntu-app-launch/app-store-base.cpp 2017-03-21 03:26:40 +0000 |
1044 | @@ -18,13 +18,9 @@ |
1045 | */ |
1046 | |
1047 | #include "app-store-base.h" |
1048 | -#include "app-store-click.h" |
1049 | #include "app-store-legacy.h" |
1050 | #include "app-store-libertine.h" |
1051 | - |
1052 | -#if ENABLE_SNAPPY |
1053 | #include "app-store-snap.h" |
1054 | -#endif |
1055 | |
1056 | namespace ubuntu |
1057 | { |
1058 | @@ -44,17 +40,12 @@ |
1059 | |
1060 | std::list<std::shared_ptr<Base>> Base::allAppStores() |
1061 | { |
1062 | - return |
1063 | - { |
1064 | - std::make_shared<Click>() /* Click */ |
1065 | - , |
1066 | - std::make_shared<Legacy>() /* Legacy */ |
1067 | - , |
1068 | - std::make_shared<Libertine>() /* Libertine */ |
1069 | -#if ENABLE_SNAPPY |
1070 | - , |
1071 | - std::make_shared<Snap>() /* Snappy */ |
1072 | -#endif |
1073 | + return { |
1074 | + std::make_shared<Legacy>() /* Legacy */ |
1075 | + , |
1076 | + std::make_shared<Libertine>() /* Libertine */ |
1077 | + , |
1078 | + std::make_shared<Snap>() /* Snappy */ |
1079 | }; |
1080 | } |
1081 | |
1082 | |
1083 | === removed file 'libubuntu-app-launch/app-store-click.cpp' |
1084 | --- libubuntu-app-launch/app-store-click.cpp 2017-03-21 03:26:39 +0000 |
1085 | +++ libubuntu-app-launch/app-store-click.cpp 1970-01-01 00:00:00 +0000 |
1086 | @@ -1,248 +0,0 @@ |
1087 | -/* |
1088 | - * Copyright © 2017 Canonical Ltd. |
1089 | - * |
1090 | - * This program is free software: you can redistribute it and/or modify it |
1091 | - * under the terms of the GNU General Public License version 3, as published |
1092 | - * by the Free Software Foundation. |
1093 | - * |
1094 | - * This program is distributed in the hope that it will be useful, but |
1095 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1096 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1097 | - * PURPOSE. See the GNU General Public License for more details. |
1098 | - * |
1099 | - * You should have received a copy of the GNU General Public License along |
1100 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1101 | - * |
1102 | - * Authors: |
1103 | - * Ted Gould <ted.gould@canonical.com> |
1104 | - */ |
1105 | - |
1106 | -#include "app-store-click.h" |
1107 | -#include "application-impl-click.h" |
1108 | -#include "registry-impl.h" |
1109 | - |
1110 | -#include <algorithm> |
1111 | - |
1112 | -namespace ubuntu |
1113 | -{ |
1114 | -namespace app_launch |
1115 | -{ |
1116 | -namespace app_store |
1117 | -{ |
1118 | - |
1119 | -std::list<AppID::AppName> manifestApps(const std::shared_ptr<JsonObject>& manifest); |
1120 | -AppID::Version manifestVersion(const std::shared_ptr<JsonObject>& manifest); |
1121 | - |
1122 | -Click::Click() |
1123 | -{ |
1124 | -} |
1125 | - |
1126 | -Click::~Click() |
1127 | -{ |
1128 | -} |
1129 | - |
1130 | -/** Tries to get the Click manifest for a package. If it can successfully |
1131 | - get the manifest returns true. |
1132 | - |
1133 | - \param package Name of the package |
1134 | - \param registry Persistent connections to use |
1135 | -*/ |
1136 | -bool Click::verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry) |
1137 | -{ |
1138 | - return registry->impl->getClickManifest(package) != nullptr; |
1139 | -} |
1140 | - |
1141 | -/** Verifies the applicaiton name by getting the list of applications |
1142 | - in the package manifest and seeing if the appname is in the list. |
1143 | - |
1144 | - \param package Name of the package |
1145 | - \param appname Name of the application |
1146 | - \param registry Persistent connections to use |
1147 | -*/ |
1148 | -bool Click::verifyAppname(const AppID::Package& package, |
1149 | - const AppID::AppName& appname, |
1150 | - const std::shared_ptr<Registry>& registry) |
1151 | -{ |
1152 | - auto manifest = registry->impl->getClickManifest(package); |
1153 | - auto apps = manifestApps(manifest); |
1154 | - |
1155 | - return std::find_if(apps.begin(), apps.end(), [&appname](const AppID::AppName& listApp) -> bool { |
1156 | - return appname.value() == listApp.value(); |
1157 | - }) != apps.end(); |
1158 | -} |
1159 | - |
1160 | -/** Finds an application name based on a wildcard search. Gets the list |
1161 | - from the manifest, and then returns a value from that list. |
1162 | - |
1163 | - \param package Name of the package |
1164 | - \param card Wildcard to search as |
1165 | - \param registry Persistent connections to use |
1166 | -*/ |
1167 | -AppID::AppName Click::findAppname(const AppID::Package& package, |
1168 | - AppID::ApplicationWildcard card, |
1169 | - const std::shared_ptr<Registry>& registry) |
1170 | -{ |
1171 | - auto manifest = registry->impl->getClickManifest(package); |
1172 | - auto apps = manifestApps(manifest); |
1173 | - |
1174 | - if (apps.empty()) |
1175 | - { |
1176 | - throw std::runtime_error("No apps in package '" + package.value() + "' to find"); |
1177 | - } |
1178 | - |
1179 | - switch (card) |
1180 | - { |
1181 | - case AppID::ApplicationWildcard::FIRST_LISTED: |
1182 | - return *apps.begin(); |
1183 | - case AppID::ApplicationWildcard::LAST_LISTED: |
1184 | - return *apps.rbegin(); |
1185 | - case AppID::ApplicationWildcard::ONLY_LISTED: |
1186 | - if (apps.size() != 1) |
1187 | - { |
1188 | - throw std::runtime_error("More than a single app in package '" + package.value() + |
1189 | - "' when requested to find only app"); |
1190 | - } |
1191 | - return *apps.begin(); |
1192 | - } |
1193 | - |
1194 | - throw std::logic_error("Got a value of the app wildcard enum that can't exist"); |
1195 | -} |
1196 | - |
1197 | -/** Find the version of a package that that is requested |
1198 | - |
1199 | - \param package Name of the package |
1200 | - \param appname Name of the application (not used) |
1201 | - \param registry Persistent connections to use |
1202 | -*/ |
1203 | -AppID::Version Click::findVersion(const AppID::Package& package, |
1204 | - const AppID::AppName& appname, |
1205 | - const std::shared_ptr<Registry>& registry) |
1206 | -{ |
1207 | - auto manifest = registry->impl->getClickManifest(package); |
1208 | - return manifestVersion(manifest); |
1209 | -} |
1210 | - |
1211 | -/** Check to see if this AppID has a desktop file that is in our link |
1212 | - farm built by Click. Click puts a symoblic link there for every |
1213 | - valid AppID. |
1214 | - |
1215 | - \param appid Application ID to check |
1216 | - \param registry Persistent connections to use |
1217 | -*/ |
1218 | -bool Click::hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry) |
1219 | -{ |
1220 | - std::string appiddesktop = std::string(appid) + ".desktop"; |
1221 | - gchar* click_link = nullptr; |
1222 | - const gchar* link_farm_dir = g_getenv("UBUNTU_APP_LAUNCH_LINK_FARM"); |
1223 | - if (G_LIKELY(link_farm_dir == nullptr)) |
1224 | - { |
1225 | - click_link = |
1226 | - g_build_filename(g_get_user_cache_dir(), "ubuntu-app-launch", "desktop", appiddesktop.c_str(), NULL); |
1227 | - } |
1228 | - else |
1229 | - { |
1230 | - click_link = g_build_filename(link_farm_dir, appiddesktop.c_str(), NULL); |
1231 | - } |
1232 | - |
1233 | - bool click = g_file_test(click_link, G_FILE_TEST_EXISTS); |
1234 | - g_free(click_link); |
1235 | - |
1236 | - return click; |
1237 | -} |
1238 | - |
1239 | -std::list<std::shared_ptr<Application>> Click::list(const std::shared_ptr<Registry>& registry) |
1240 | -{ |
1241 | - std::list<std::shared_ptr<Application>> applist; |
1242 | - |
1243 | - try |
1244 | - { |
1245 | - for (auto pkg : registry->impl->getClickPackages()) |
1246 | - { |
1247 | - try |
1248 | - { |
1249 | - auto manifest = registry->impl->getClickManifest(pkg); |
1250 | - |
1251 | - for (auto appname : manifestApps(manifest)) |
1252 | - { |
1253 | - try |
1254 | - { |
1255 | - AppID appid{pkg, appname, manifestVersion(manifest)}; |
1256 | - auto app = std::make_shared<app_impls::Click>(appid, manifest, registry); |
1257 | - applist.emplace_back(app); |
1258 | - } |
1259 | - catch (std::runtime_error& e) |
1260 | - { |
1261 | - g_debug("Unable to create Click for application '%s' in package '%s': %s", |
1262 | - appname.value().c_str(), pkg.value().c_str(), e.what()); |
1263 | - } |
1264 | - } |
1265 | - } |
1266 | - catch (std::runtime_error& e) |
1267 | - { |
1268 | - g_debug("Unable to get information to build Click app on package '%s': %s", pkg.value().c_str(), |
1269 | - e.what()); |
1270 | - } |
1271 | - } |
1272 | - } |
1273 | - catch (std::runtime_error& e) |
1274 | - { |
1275 | - g_debug("Unable to get packages from Click database: %s", e.what()); |
1276 | - } |
1277 | - |
1278 | - return applist; |
1279 | -} |
1280 | - |
1281 | -std::shared_ptr<app_impls::Base> Click::create(const AppID& appid, const std::shared_ptr<Registry>& registry) |
1282 | -{ |
1283 | - return std::make_shared<app_impls::Click>(appid, registry); |
1284 | -} |
1285 | - |
1286 | -std::list<AppID::AppName> manifestApps(const std::shared_ptr<JsonObject>& manifest) |
1287 | -{ |
1288 | - JsonObject* hooks = nullptr; |
1289 | - if (!json_object_has_member(manifest.get(), "hooks") || |
1290 | - (hooks = json_object_get_object_member(manifest.get(), "hooks")) == nullptr) |
1291 | - { |
1292 | - throw std::runtime_error("Manifest does not have a 'hooks' field: " + Registry::Impl::printJson(manifest)); |
1293 | - } |
1294 | - |
1295 | - auto gapps = json_object_get_members(hooks); |
1296 | - if (gapps == nullptr) |
1297 | - { |
1298 | - throw std::runtime_error("GLib JSON confusion, please talk to your library vendor"); |
1299 | - } |
1300 | - |
1301 | - std::list<AppID::AppName> apps; |
1302 | - |
1303 | - for (GList* item = gapps; item != nullptr; item = g_list_next(item)) |
1304 | - { |
1305 | - auto appname = (const gchar*)item->data; |
1306 | - |
1307 | - auto hooklist = json_object_get_object_member(hooks, appname); |
1308 | - |
1309 | - if (json_object_has_member(hooklist, "desktop") == TRUE) |
1310 | - { |
1311 | - apps.emplace_back(AppID::AppName::from_raw(appname)); |
1312 | - } |
1313 | - } |
1314 | - |
1315 | - g_list_free(gapps); |
1316 | - return apps; |
1317 | -} |
1318 | - |
1319 | -AppID::Version manifestVersion(const std::shared_ptr<JsonObject>& manifest) |
1320 | -{ |
1321 | - const gchar* cstr = nullptr; |
1322 | - if (!json_object_has_member(manifest.get(), "version") || |
1323 | - (cstr = json_object_get_string_member(manifest.get(), "version")) == nullptr) |
1324 | - { |
1325 | - throw std::runtime_error("Unable to find version number in manifest: " + Registry::Impl::printJson(manifest)); |
1326 | - } |
1327 | - |
1328 | - auto cppstr = AppID::Version::from_raw(cstr); |
1329 | - return cppstr; |
1330 | -} |
1331 | - |
1332 | -} // namespace app_store |
1333 | -} // namespace app_launch |
1334 | -} // namespace ubuntu |
1335 | |
1336 | === removed file 'libubuntu-app-launch/app-store-click.h' |
1337 | --- libubuntu-app-launch/app-store-click.h 2017-03-21 03:26:39 +0000 |
1338 | +++ libubuntu-app-launch/app-store-click.h 1970-01-01 00:00:00 +0000 |
1339 | @@ -1,60 +0,0 @@ |
1340 | -/* |
1341 | - * Copyright © 2017 Canonical Ltd. |
1342 | - * |
1343 | - * This program is free software: you can redistribute it and/or modify it |
1344 | - * under the terms of the GNU General Public License version 3, as published |
1345 | - * by the Free Software Foundation. |
1346 | - * |
1347 | - * This program is distributed in the hope that it will be useful, but |
1348 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1349 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1350 | - * PURPOSE. See the GNU General Public License for more details. |
1351 | - * |
1352 | - * You should have received a copy of the GNU General Public License along |
1353 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1354 | - * |
1355 | - * Authors: |
1356 | - * Ted Gould <ted.gould@canonical.com> |
1357 | - */ |
1358 | - |
1359 | -#pragma once |
1360 | - |
1361 | -#include "app-store-base.h" |
1362 | - |
1363 | -namespace ubuntu |
1364 | -{ |
1365 | -namespace app_launch |
1366 | -{ |
1367 | -namespace app_store |
1368 | -{ |
1369 | - |
1370 | -class Click : public Base |
1371 | -{ |
1372 | -public: |
1373 | - Click(); |
1374 | - virtual ~Click(); |
1375 | - |
1376 | - /* Discover tools */ |
1377 | - virtual bool verifyPackage(const AppID::Package& package, const std::shared_ptr<Registry>& registry) override; |
1378 | - virtual bool verifyAppname(const AppID::Package& package, |
1379 | - const AppID::AppName& appname, |
1380 | - const std::shared_ptr<Registry>& registry) override; |
1381 | - virtual AppID::AppName findAppname(const AppID::Package& package, |
1382 | - AppID::ApplicationWildcard card, |
1383 | - const std::shared_ptr<Registry>& registry) override; |
1384 | - virtual AppID::Version findVersion(const AppID::Package& package, |
1385 | - const AppID::AppName& appname, |
1386 | - const std::shared_ptr<Registry>& registry) override; |
1387 | - virtual bool hasAppId(const AppID& appid, const std::shared_ptr<Registry>& registry) override; |
1388 | - |
1389 | - /* Possible apps */ |
1390 | - virtual std::list<std::shared_ptr<Application>> list(const std::shared_ptr<Registry>& registry) override; |
1391 | - |
1392 | - /* Application Creation */ |
1393 | - virtual std::shared_ptr<app_impls::Base> create(const AppID& appid, |
1394 | - const std::shared_ptr<Registry>& registry) override; |
1395 | -}; |
1396 | - |
1397 | -} // namespace app_store |
1398 | -} // namespace app_launch |
1399 | -} // namespace ubuntu |
1400 | |
1401 | === modified file 'libubuntu-app-launch/app-store-snap.cpp' |
1402 | --- libubuntu-app-launch/app-store-snap.cpp 2017-03-21 03:26:39 +0000 |
1403 | +++ libubuntu-app-launch/app-store-snap.cpp 2017-03-21 03:26:40 +0000 |
1404 | @@ -109,6 +109,12 @@ |
1405 | } |
1406 | |
1407 | auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package); |
1408 | + |
1409 | + if (!pkgInfo) |
1410 | + { |
1411 | + return false; |
1412 | + } |
1413 | + |
1414 | return pkgInfo->appnames.find(appname) != pkgInfo->appnames.end(); |
1415 | } |
1416 | |
1417 | @@ -125,6 +131,11 @@ |
1418 | { |
1419 | auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package); |
1420 | |
1421 | + if (!pkgInfo) |
1422 | + { |
1423 | + throw std::runtime_error("Packge '" + package.value() + "' doesn't have valid info."); |
1424 | + } |
1425 | + |
1426 | if (pkgInfo->appnames.empty()) |
1427 | { |
1428 | throw std::runtime_error("No apps in package '" + package.value() + "' to find"); |
1429 | @@ -159,7 +170,14 @@ |
1430 | const std::shared_ptr<Registry>& registry) |
1431 | { |
1432 | auto pkgInfo = registry->impl->snapdInfo.pkgInfo(package); |
1433 | - return AppID::Version::from_raw(pkgInfo->revision); |
1434 | + if (pkgInfo) |
1435 | + { |
1436 | + return AppID::Version::from_raw(pkgInfo->revision); |
1437 | + } |
1438 | + else |
1439 | + { |
1440 | + return AppID::Version::from_raw({}); |
1441 | + } |
1442 | } |
1443 | |
1444 | /** Operator to compare apps for our sets */ |
1445 | |
1446 | === modified file 'libubuntu-app-launch/application-impl-base.cpp' |
1447 | --- libubuntu-app-launch/application-impl-base.cpp 2017-03-21 03:26:39 +0000 |
1448 | +++ libubuntu-app-launch/application-impl-base.cpp 2017-03-21 03:26:40 +0000 |
1449 | @@ -24,9 +24,9 @@ |
1450 | #include <numeric> |
1451 | |
1452 | #include "application-impl-base.h" |
1453 | -#include "helpers.h" |
1454 | #include "registry-impl.h" |
1455 | #include "second-exec-core.h" |
1456 | +#include "utils.h" |
1457 | |
1458 | extern "C" { |
1459 | #include "ubuntu-app-launch-trace.h" |
1460 | |
1461 | === removed file 'libubuntu-app-launch/application-impl-click.cpp' |
1462 | --- libubuntu-app-launch/application-impl-click.cpp 2017-03-21 03:26:39 +0000 |
1463 | +++ libubuntu-app-launch/application-impl-click.cpp 1970-01-01 00:00:00 +0000 |
1464 | @@ -1,189 +0,0 @@ |
1465 | -/* |
1466 | - * Copyright © 2016 Canonical Ltd. |
1467 | - * |
1468 | - * This program is free software: you can redistribute it and/or modify it |
1469 | - * under the terms of the GNU General Public License version 3, as published |
1470 | - * by the Free Software Foundation. |
1471 | - * |
1472 | - * This program is distributed in the hope that it will be useful, but |
1473 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1474 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1475 | - * PURPOSE. See the GNU General Public License for more details. |
1476 | - * |
1477 | - * You should have received a copy of the GNU General Public License along |
1478 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1479 | - * |
1480 | - * Authors: |
1481 | - * Ted Gould <ted.gould@canonical.com> |
1482 | - */ |
1483 | - |
1484 | -#include "application-impl-click.h" |
1485 | -#include "application-info-desktop.h" |
1486 | -#include "registry-impl.h" |
1487 | - |
1488 | -#include <algorithm> |
1489 | - |
1490 | -namespace ubuntu |
1491 | -{ |
1492 | -namespace app_launch |
1493 | -{ |
1494 | -namespace app_impls |
1495 | -{ |
1496 | - |
1497 | -std::pair<std::shared_ptr<GKeyFile>, std::string> manifestAppDesktop(const std::shared_ptr<JsonObject>& manifest, |
1498 | - const std::string& package, |
1499 | - const std::string& app, |
1500 | - const std::string& clickDir); |
1501 | - |
1502 | -Click::Click(const AppID& appid, const std::shared_ptr<Registry>& registry) |
1503 | - : Click(appid, registry->impl->getClickManifest(appid.package), registry) |
1504 | -{ |
1505 | -} |
1506 | - |
1507 | -Click::Click(const AppID& appid, const std::shared_ptr<JsonObject>& manifest, const std::shared_ptr<Registry>& registry) |
1508 | - : Base(registry) |
1509 | - , _appid(appid) |
1510 | - , _manifest(manifest) |
1511 | - , _clickDir(registry->impl->getClickDir(appid.package)) |
1512 | -{ |
1513 | - std::tie(_keyfile, desktopPath_) = manifestAppDesktop(_manifest, appid.package, appid.appname, _clickDir); |
1514 | - if (!_keyfile) |
1515 | - throw std::runtime_error{"No keyfile found for click application: " + std::string(appid)}; |
1516 | - |
1517 | - g_debug("Application Click object for appid '%s'", std::string(appid).c_str()); |
1518 | -} |
1519 | - |
1520 | -AppID Click::appId() |
1521 | -{ |
1522 | - return _appid; |
1523 | -} |
1524 | - |
1525 | -std::shared_ptr<Application::Info> Click::info() |
1526 | -{ |
1527 | - if (!_info) |
1528 | - { |
1529 | - _info = std::make_shared<app_info::Desktop>(appId(), _keyfile, _clickDir, _clickDir, |
1530 | - app_info::DesktopFlags::NONE, nullptr); |
1531 | - } |
1532 | - |
1533 | - return _info; |
1534 | -} |
1535 | - |
1536 | -AppID::Version manifestVersion(const std::shared_ptr<JsonObject>& manifest) |
1537 | -{ |
1538 | - const gchar* cstr = nullptr; |
1539 | - if (!json_object_has_member(manifest.get(), "version") || |
1540 | - (cstr = json_object_get_string_member(manifest.get(), "version")) == nullptr) |
1541 | - { |
1542 | - throw std::runtime_error("Unable to find version number in manifest: " + Registry::Impl::printJson(manifest)); |
1543 | - } |
1544 | - |
1545 | - auto cppstr = AppID::Version::from_raw(cstr); |
1546 | - return cppstr; |
1547 | -} |
1548 | - |
1549 | -std::pair<std::shared_ptr<GKeyFile>, std::string> manifestAppDesktop(const std::shared_ptr<JsonObject>& manifest, |
1550 | - const std::string& package, |
1551 | - const std::string& app, |
1552 | - const std::string& clickDir) |
1553 | -{ |
1554 | - if (!manifest) |
1555 | - { |
1556 | - throw std::runtime_error("No manifest for package '" + package + "'"); |
1557 | - } |
1558 | - |
1559 | - JsonObject* hooks = nullptr; |
1560 | - if (!json_object_has_member(manifest.get(), "hooks") || |
1561 | - (hooks = json_object_get_object_member(manifest.get(), "hooks")) == nullptr) |
1562 | - { |
1563 | - throw std::runtime_error("Manifest for application '" + app + |
1564 | - "' does not have a 'hooks' field: " + Registry::Impl::printJson(manifest)); |
1565 | - } |
1566 | - |
1567 | - auto gapps = json_object_get_members(hooks); |
1568 | - if (gapps == nullptr) |
1569 | - { |
1570 | - throw std::runtime_error("GLib JSON confusion, please talk to your library vendor"); |
1571 | - } |
1572 | - else |
1573 | - { |
1574 | - g_list_free(gapps); |
1575 | - } |
1576 | - |
1577 | - JsonObject* hooklist = nullptr; |
1578 | - if (!json_object_has_member(hooks, app.c_str()) || |
1579 | - (hooklist = json_object_get_object_member(hooks, app.c_str())) == nullptr) |
1580 | - { |
1581 | - throw std::runtime_error("Manifest for does not have an application '" + app + |
1582 | - "': " + Registry::Impl::printJson(manifest)); |
1583 | - } |
1584 | - |
1585 | - auto desktoppath = json_object_get_string_member(hooklist, "desktop"); |
1586 | - if (desktoppath == nullptr) |
1587 | - throw std::runtime_error("Manifest for application '" + app + |
1588 | - "' does not have a 'desktop' hook: " + Registry::Impl::printJson(manifest)); |
1589 | - |
1590 | - auto path = std::shared_ptr<gchar>(g_build_filename(clickDir.c_str(), desktoppath, nullptr), g_free); |
1591 | - |
1592 | - std::shared_ptr<GKeyFile> keyfile(g_key_file_new(), g_key_file_free); |
1593 | - GError* error = nullptr; |
1594 | - g_key_file_load_from_file(keyfile.get(), path.get(), G_KEY_FILE_NONE, &error); |
1595 | - if (error != nullptr) |
1596 | - { |
1597 | - auto perror = std::shared_ptr<GError>(error, g_error_free); |
1598 | - throw std::runtime_error(perror.get()->message); |
1599 | - } |
1600 | - |
1601 | - return std::make_pair(keyfile, std::string(path.get())); |
1602 | -} |
1603 | - |
1604 | -std::vector<std::shared_ptr<Application::Instance>> Click::instances() |
1605 | -{ |
1606 | - auto vbase = _registry->impl->jobs->instances(appId(), "application-click"); |
1607 | - return std::vector<std::shared_ptr<Application::Instance>>(vbase.begin(), vbase.end()); |
1608 | -} |
1609 | - |
1610 | -/** Grabs all the environment variables for the application to |
1611 | - launch in. It sets up the confinement ones and then adds in |
1612 | - the APP_EXEC line and whether to use XMir */ |
1613 | -std::list<std::pair<std::string, std::string>> Click::launchEnv() |
1614 | -{ |
1615 | - auto retval = confinedEnv(_appid.package, _clickDir); |
1616 | - |
1617 | - retval.emplace_back(std::make_pair("APP_DIR", _clickDir)); |
1618 | - retval.emplace_back(std::make_pair("APP_DESKTOP_FILE_PATH", desktopPath_)); |
1619 | - |
1620 | - retval.emplace_back(std::make_pair("QML2_IMPORT_PATH", _clickDir + "/lib/" + UBUNTU_APP_LAUNCH_ARCH + "/qml")); |
1621 | - |
1622 | - info(); |
1623 | - |
1624 | - retval.emplace_back(std::make_pair("APP_XMIR_ENABLE", _info->xMirEnable().value() ? "1" : "0")); |
1625 | - retval.emplace_back(std::make_pair("APP_EXEC", _info->execLine().value())); |
1626 | - |
1627 | - retval.emplace_back(std::make_pair("APP_EXEC_POLICY", std::string(appId()))); |
1628 | - |
1629 | - return retval; |
1630 | -} |
1631 | - |
1632 | -std::shared_ptr<Application::Instance> Click::launch(const std::vector<Application::URL>& urls) |
1633 | -{ |
1634 | - std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); }; |
1635 | - return _registry->impl->jobs->launch(appId(), "application-click", {}, urls, jobs::manager::launchMode::STANDARD, |
1636 | - envfunc); |
1637 | -} |
1638 | - |
1639 | -std::shared_ptr<Application::Instance> Click::launchTest(const std::vector<Application::URL>& urls) |
1640 | -{ |
1641 | - std::function<std::list<std::pair<std::string, std::string>>(void)> envfunc = [this]() { return launchEnv(); }; |
1642 | - return _registry->impl->jobs->launch(appId(), "application-click", {}, urls, jobs::manager::launchMode::TEST, |
1643 | - envfunc); |
1644 | -} |
1645 | - |
1646 | -std::shared_ptr<Application::Instance> Click::findInstance(const std::string& instanceid) |
1647 | -{ |
1648 | - return _registry->impl->jobs->existing(appId(), "application-click", instanceid, std::vector<Application::URL>{}); |
1649 | -} |
1650 | - |
1651 | -} // namespace app_impls |
1652 | -} // namespace app_launch |
1653 | -} // namespace ubuntu |
1654 | |
1655 | === removed file 'libubuntu-app-launch/application-impl-click.h' |
1656 | --- libubuntu-app-launch/application-impl-click.h 2017-03-21 03:26:39 +0000 |
1657 | +++ libubuntu-app-launch/application-impl-click.h 1970-01-01 00:00:00 +0000 |
1658 | @@ -1,82 +0,0 @@ |
1659 | -/* |
1660 | - * Copyright © 2016 Canonical Ltd. |
1661 | - * |
1662 | - * This program is free software: you can redistribute it and/or modify it |
1663 | - * under the terms of the GNU General Public License version 3, as published |
1664 | - * by the Free Software Foundation. |
1665 | - * |
1666 | - * This program is distributed in the hope that it will be useful, but |
1667 | - * WITHOUT ANY WARRANTY; without even the implied warranties of |
1668 | - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1669 | - * PURPOSE. See the GNU General Public License for more details. |
1670 | - * |
1671 | - * You should have received a copy of the GNU General Public License along |
1672 | - * with this program. If not, see <http://www.gnu.org/licenses/>. |
1673 | - * |
1674 | - * Authors: |
1675 | - * Ted Gould <ted.gould@canonical.com> |
1676 | - */ |
1677 | - |
1678 | -#include "application-impl-base.h" |
1679 | -#include "application-info-desktop.h" |
1680 | - |
1681 | -#include <gio/gdesktopappinfo.h> |
1682 | -#include <json-glib/json-glib.h> |
1683 | - |
1684 | -#pragma once |
1685 | - |
1686 | -namespace ubuntu |
1687 | -{ |
1688 | -namespace app_launch |
1689 | -{ |
1690 | -namespace app_impls |
1691 | -{ |
1692 | - |
1693 | -/** Application Implmentation for Click packages. Click packages |
1694 | - are installed via the click tool and have information avaialable |
1695 | - on them via libclick. There is one version per-user on the system |
1696 | - and a Ubuntu App Launch hook makes a link to each of those versions |
1697 | - in the user's cache directory. Click ensures this is up-to-date. |
1698 | - |
1699 | - Application IDs for Click packages are the standard it was built on. |
1700 | - Typically a package name is "$(application).$(developer id)" though |
1701 | - there isn't a requirement in the local Click tools to require that. The |
1702 | - appname element is gotten from the JSON manifest in the Click package and |
1703 | - should reference a desktop file. All Click packages also have a version. |
1704 | - |
1705 | - More info: http://click.readthedocs.io/ |
1706 | -*/ |
1707 | -class Click : public Base |
1708 | -{ |
1709 | -public: |
1710 | - Click(const AppID& appid, const std::shared_ptr<Registry>& registry); |
1711 | - Click(const AppID& appid, const std::shared_ptr<JsonObject>& manifest, const std::shared_ptr<Registry>& registry); |
1712 | - |
1713 | - AppID appId() override; |
1714 | - |
1715 | - std::shared_ptr<Info> info() override; |
1716 | - |
1717 | - std::vector<std::shared_ptr<Instance>> instances() override; |
1718 | - |
1719 | - std::shared_ptr<Instance> launch(const std::vector<Application::URL>& urls = {}) override; |
1720 | - std::shared_ptr<Instance> launchTest(const std::vector<Application::URL>& urls = {}) override; |
1721 | - |
1722 | - virtual std::shared_ptr<Application::Instance> findInstance(const std::string& instanceid) override; |
1723 | - |
1724 | -private: |
1725 | - AppID _appid; |
1726 | - |
1727 | - std::shared_ptr<JsonObject> _manifest; |
1728 | - |
1729 | - std::string _clickDir; |
1730 | - std::shared_ptr<GKeyFile> _keyfile; |
1731 | - std::string desktopPath_; |
1732 | - |
1733 | - std::shared_ptr<app_info::Desktop> _info; |
1734 | - |
1735 | - std::list<std::pair<std::string, std::string>> launchEnv(); |
1736 | -}; |
1737 | - |
1738 | -} // namespace app_impls |
1739 | -} // namespace app_launch |
1740 | -} // namespace ubuntu |
1741 | |
1742 | === modified file 'libubuntu-app-launch/glib-thread.cpp' |
1743 | --- libubuntu-app-launch/glib-thread.cpp 2016-08-12 23:13:00 +0000 |
1744 | +++ libubuntu-app-launch/glib-thread.cpp 2017-03-21 03:26:40 +0000 |
1745 | @@ -119,7 +119,7 @@ |
1746 | return _cancel; |
1747 | } |
1748 | |
1749 | -void ContextThread::simpleSource(std::function<GSource*()> srcBuilder, std::function<void()> work) |
1750 | +guint ContextThread::simpleSource(std::function<GSource*()> srcBuilder, std::function<void()> work) |
1751 | { |
1752 | if (isCancelled()) |
1753 | { |
1754 | @@ -144,22 +144,33 @@ |
1755 | delete heapWork; |
1756 | }); |
1757 | |
1758 | - g_source_attach(source.get(), _context.get()); |
1759 | -} |
1760 | - |
1761 | -void ContextThread::executeOnThread(std::function<void()> work) |
1762 | -{ |
1763 | - simpleSource(g_idle_source_new, work); |
1764 | -} |
1765 | - |
1766 | -void ContextThread::timeout(const std::chrono::milliseconds& length, std::function<void()> work) |
1767 | -{ |
1768 | - simpleSource([length]() { return g_timeout_source_new(length.count()); }, work); |
1769 | -} |
1770 | - |
1771 | -void ContextThread::timeoutSeconds(const std::chrono::seconds& length, std::function<void()> work) |
1772 | -{ |
1773 | - simpleSource([length]() { return g_timeout_source_new_seconds(length.count()); }, work); |
1774 | + return g_source_attach(source.get(), _context.get()); |
1775 | +} |
1776 | + |
1777 | +guint ContextThread::executeOnThread(std::function<void()> work) |
1778 | +{ |
1779 | + return simpleSource(g_idle_source_new, work); |
1780 | +} |
1781 | + |
1782 | +guint ContextThread::timeout(const std::chrono::milliseconds& length, std::function<void()> work) |
1783 | +{ |
1784 | + return simpleSource([length]() { return g_timeout_source_new(length.count()); }, work); |
1785 | +} |
1786 | + |
1787 | +guint ContextThread::timeoutSeconds(const std::chrono::seconds& length, std::function<void()> work) |
1788 | +{ |
1789 | + return simpleSource([length]() { return g_timeout_source_new_seconds(length.count()); }, work); |
1790 | +} |
1791 | + |
1792 | +void ContextThread::removeSource(guint sourceid) |
1793 | +{ |
1794 | + auto source = g_main_context_find_source_by_id(_context.get(), sourceid); |
1795 | + if (source == nullptr) |
1796 | + { |
1797 | + return; |
1798 | + } |
1799 | + |
1800 | + g_source_destroy(source); |
1801 | } |
1802 | |
1803 | } // ns GLib |
1804 | |
1805 | === modified file 'libubuntu-app-launch/glib-thread.h' |
1806 | --- libubuntu-app-launch/glib-thread.h 2016-08-24 02:53:12 +0000 |
1807 | +++ libubuntu-app-launch/glib-thread.h 2017-03-21 03:26:40 +0000 |
1808 | @@ -46,7 +46,7 @@ |
1809 | bool isCancelled(); |
1810 | std::shared_ptr<GCancellable> getCancellable(); |
1811 | |
1812 | - void executeOnThread(std::function<void()> work); |
1813 | + guint executeOnThread(std::function<void()> work); |
1814 | template <typename T> |
1815 | auto executeOnThread(std::function<T()> work) -> T |
1816 | { |
1817 | @@ -75,21 +75,23 @@ |
1818 | return future.get(); |
1819 | } |
1820 | |
1821 | - void timeout(const std::chrono::milliseconds& length, std::function<void()> work); |
1822 | + guint timeout(const std::chrono::milliseconds& length, std::function<void()> work); |
1823 | template <class Rep, class Period> |
1824 | - void timeout(const std::chrono::duration<Rep, Period>& length, std::function<void()> work) |
1825 | + guint timeout(const std::chrono::duration<Rep, Period>& length, std::function<void()> work) |
1826 | { |
1827 | return timeout(std::chrono::duration_cast<std::chrono::milliseconds>(length), work); |
1828 | } |
1829 | |
1830 | - void timeoutSeconds(const std::chrono::seconds& length, std::function<void()> work); |
1831 | + guint timeoutSeconds(const std::chrono::seconds& length, std::function<void()> work); |
1832 | template <class Rep, class Period> |
1833 | - void timeoutSeconds(const std::chrono::duration<Rep, Period>& length, std::function<void()> work) |
1834 | + guint timeoutSeconds(const std::chrono::duration<Rep, Period>& length, std::function<void()> work) |
1835 | { |
1836 | return timeoutSeconds(std::chrono::duration_cast<std::chrono::seconds>(length), work); |
1837 | } |
1838 | |
1839 | + void removeSource(guint sourceid); |
1840 | + |
1841 | private: |
1842 | - void simpleSource(std::function<GSource*()> srcBuilder, std::function<void()> work); |
1843 | + guint simpleSource(std::function<GSource*()> srcBuilder, std::function<void()> work); |
1844 | }; |
1845 | } |
1846 | |
1847 | === modified file 'libubuntu-app-launch/helper.cpp' |
1848 | --- libubuntu-app-launch/helper.cpp 2017-03-21 03:26:39 +0000 |
1849 | +++ libubuntu-app-launch/helper.cpp 2017-03-21 03:26:40 +0000 |
1850 | @@ -86,7 +86,7 @@ |
1851 | std::vector<std::shared_ptr<Helper::Instance>> Base::instances() |
1852 | { |
1853 | auto insts = _registry->impl->jobs->instances(_appid, _type.value()); |
1854 | - std::vector<std::shared_ptr<Helper::Instance>> wrapped; |
1855 | + std::vector<std::shared_ptr<Helper::Instance>> wrapped{insts.size()}; |
1856 | |
1857 | std::transform(insts.begin(), insts.end(), wrapped.begin(), |
1858 | [](std::shared_ptr<jobs::instance::Base>& inst) { return std::make_shared<BaseInstance>(inst); }); |
1859 | @@ -110,8 +110,12 @@ |
1860 | std::vector<Application::URL> appURL(const std::vector<Helper::URL>& in) |
1861 | { |
1862 | std::vector<Application::URL> out; |
1863 | - std::transform(in.begin(), in.end(), out.begin(), |
1864 | - [](Helper::URL url) { return Application::URL::from_raw(url.value()); }); |
1865 | + |
1866 | + for (const auto& hurl : in) |
1867 | + { |
1868 | + out.push_back(Application::URL::from_raw(hurl.value())); |
1869 | + } |
1870 | + |
1871 | return out; |
1872 | } |
1873 | |
1874 | @@ -191,6 +195,8 @@ |
1875 | return accum.empty() ? addon : accum + " " + addon; |
1876 | }))); |
1877 | |
1878 | + envs.emplace_back(std::make_pair("HELPER_TYPE", _type.value())); |
1879 | + |
1880 | return envs; |
1881 | } |
1882 | |
1883 | @@ -206,14 +212,17 @@ |
1884 | class MirFDProxy |
1885 | { |
1886 | public: |
1887 | + std::shared_ptr<Registry> reg_; |
1888 | int mirfd; |
1889 | std::shared_ptr<proxySocketDemangler> skel; |
1890 | guint handle; |
1891 | std::string path; |
1892 | std::string name; |
1893 | + guint timeout{0}; |
1894 | |
1895 | MirFDProxy(MirPromptSession* session, const AppID& appid, const std::shared_ptr<Registry>& reg) |
1896 | - : name(g_dbus_connection_get_unique_name(reg->impl->_dbus.get())) |
1897 | + : reg_(reg) |
1898 | + , name(g_dbus_connection_get_unique_name(reg->impl->_dbus.get())) |
1899 | { |
1900 | if (appid.empty()) |
1901 | { |
1902 | @@ -291,6 +300,7 @@ |
1903 | |
1904 | ~MirFDProxy() |
1905 | { |
1906 | + g_debug("Mir Prompt Proxy shutdown"); |
1907 | if (mirfd != 0) |
1908 | { |
1909 | close(mirfd); |
1910 | @@ -304,6 +314,11 @@ |
1911 | g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(skel.get())); |
1912 | } |
1913 | |
1914 | + void setTimeout(guint timeoutin) |
1915 | + { |
1916 | + timeout = timeoutin; |
1917 | + } |
1918 | + |
1919 | static std::string dbusSafe(const std::string& in) |
1920 | { |
1921 | std::string out = in; |
1922 | @@ -347,6 +362,13 @@ |
1923 | } |
1924 | |
1925 | mirfd = 0; |
1926 | + |
1927 | + /* Remove the timeout on the mainloop */ |
1928 | + auto reg = reg_; |
1929 | + auto timeoutlocal = timeout; |
1930 | + |
1931 | + reg->impl->thread.executeOnThread([reg, timeoutlocal]() { reg->impl->thread.removeSource(timeoutlocal); }); |
1932 | + |
1933 | return true; |
1934 | } |
1935 | |
1936 | @@ -391,7 +413,8 @@ |
1937 | |
1938 | /* This will maintain a reference to the proxy for two |
1939 | seconds. And then it'll be dropped. */ |
1940 | - _registry->impl->thread.timeout(std::chrono::seconds{2}, [proxy]() { g_debug("Mir Proxy Timeout"); }); |
1941 | + proxy->setTimeout( |
1942 | + _registry->impl->thread.timeout(std::chrono::seconds{2}, [proxy]() { g_debug("Mir Proxy Timeout"); })); |
1943 | |
1944 | return std::make_shared<BaseInstance>(_registry->impl->jobs->launch( |
1945 | _appid, _type.value(), genInstanceId(), appURL(urls), jobs::manager::launchMode::STANDARD, envfunc)); |
1946 | |
1947 | === modified file 'libubuntu-app-launch/jobs-base.cpp' |
1948 | --- libubuntu-app-launch/jobs-base.cpp 2017-03-21 03:26:39 +0000 |
1949 | +++ libubuntu-app-launch/jobs-base.cpp 2017-03-21 03:26:40 +0000 |
1950 | @@ -39,7 +39,7 @@ |
1951 | |
1952 | Base::Base(const std::shared_ptr<Registry>& registry) |
1953 | : registry_(registry) |
1954 | - , allApplicationJobs_{"application-click", "application-legacy", "application-snap"} |
1955 | + , allApplicationJobs_{"application-legacy", "application-snap"} |
1956 | , dbus_(registry->impl->_dbus) |
1957 | { |
1958 | } |
1959 | @@ -84,13 +84,20 @@ |
1960 | return; |
1961 | } |
1962 | |
1963 | - auto reg = registry_.lock(); |
1964 | - |
1965 | - auto appId = AppID::find(reg, appid); |
1966 | - auto app = Application::create(appId, reg); |
1967 | - auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid); |
1968 | - |
1969 | - sig_appStarted(app, inst); |
1970 | + try |
1971 | + { |
1972 | + auto reg = registry_.lock(); |
1973 | + |
1974 | + auto appId = AppID::find(reg, appid); |
1975 | + auto app = Application::create(appId, reg); |
1976 | + auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid); |
1977 | + |
1978 | + sig_appStarted(app, inst); |
1979 | + } |
1980 | + catch (std::runtime_error& e) |
1981 | + { |
1982 | + g_warning("Error in appStarted signal from job: %s", e.what()); |
1983 | + } |
1984 | }); |
1985 | }); |
1986 | |
1987 | @@ -107,13 +114,20 @@ |
1988 | return; |
1989 | } |
1990 | |
1991 | - auto reg = registry_.lock(); |
1992 | - |
1993 | - auto appId = AppID::find(reg, appid); |
1994 | - auto app = Application::create(appId, reg); |
1995 | - auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid); |
1996 | - |
1997 | - sig_appStopped(app, inst); |
1998 | + try |
1999 | + { |
2000 | + auto reg = registry_.lock(); |
2001 | + |
2002 | + auto appId = AppID::find(reg, appid); |
2003 | + auto app = Application::create(appId, reg); |
2004 | + auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid); |
2005 | + |
2006 | + sig_appStopped(app, inst); |
2007 | + } |
2008 | + catch (std::runtime_error& e) |
2009 | + { |
2010 | + g_warning("Error in appStopped signal from job: %s", e.what()); |
2011 | + } |
2012 | }); |
2013 | }); |
2014 | |
2015 | @@ -132,13 +146,20 @@ |
2016 | return; |
2017 | } |
2018 | |
2019 | - auto reg = registry_.lock(); |
2020 | - |
2021 | - auto appId = AppID::find(reg, appid); |
2022 | - auto app = Application::create(appId, reg); |
2023 | - auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid); |
2024 | - |
2025 | - sig_appFailed(app, inst, reason); |
2026 | + try |
2027 | + { |
2028 | + auto reg = registry_.lock(); |
2029 | + |
2030 | + auto appId = AppID::find(reg, appid); |
2031 | + auto app = Application::create(appId, reg); |
2032 | + auto inst = std::dynamic_pointer_cast<app_impls::Base>(app)->findInstance(instanceid); |
2033 | + |
2034 | + sig_appFailed(app, inst, reason); |
2035 | + } |
2036 | + catch (std::runtime_error& e) |
2037 | + { |
2038 | + g_warning("Error in appFailed signal from job: %s", e.what()); |
2039 | + } |
2040 | }); |
2041 | }); |
2042 | |
2043 | @@ -487,16 +508,23 @@ |
2044 | return; |
2045 | } |
2046 | |
2047 | - auto vparams = std::shared_ptr<GVariant>(g_variant_ref(params), g_variant_unref); |
2048 | - auto conn = std::shared_ptr<GDBusConnection>(reinterpret_cast<GDBusConnection*>(g_object_ref(cconn)), |
2049 | - [](GDBusConnection* con) { g_clear_object(&con); }); |
2050 | - std::string sender = csender; |
2051 | - std::shared_ptr<Application> app; |
2052 | - std::shared_ptr<Application::Instance> instance; |
2053 | - |
2054 | - std::tie(app, instance) = managerParams(vparams, reg); |
2055 | - |
2056 | - data->func(reg, app, instance, conn, sender, vparams); |
2057 | + try |
2058 | + { |
2059 | + auto vparams = std::shared_ptr<GVariant>(g_variant_ref(params), g_variant_unref); |
2060 | + auto conn = std::shared_ptr<GDBusConnection>(reinterpret_cast<GDBusConnection*>(g_object_ref(cconn)), |
2061 | + [](GDBusConnection* con) { g_clear_object(&con); }); |
2062 | + std::string sender = csender; |
2063 | + std::shared_ptr<Application> app; |
2064 | + std::shared_ptr<Application::Instance> instance; |
2065 | + |
2066 | + std::tie(app, instance) = managerParams(vparams, reg); |
2067 | + |
2068 | + data->func(reg, app, instance, conn, sender, vparams); |
2069 | + } |
2070 | + catch (std::runtime_error& e) |
2071 | + { |
2072 | + g_warning("Unable to call signal handler for manager signal: %s", e.what()); |
2073 | + } |
2074 | }, |
2075 | focusdata, |
2076 | [](gpointer user_data) { |
2077 | @@ -632,7 +660,14 @@ |
2078 | continue; |
2079 | } |
2080 | |
2081 | - apps.emplace_back(Application::create(id, registry)); |
2082 | + try |
2083 | + { |
2084 | + apps.emplace_back(Application::create(id, registry)); |
2085 | + } |
2086 | + catch (std::runtime_error& e) |
2087 | + { |
2088 | + g_debug("Error adding appid '%s' to running apps list: %s", appid.c_str(), e.what()); |
2089 | + } |
2090 | } |
2091 | |
2092 | return apps; |
2093 | |
2094 | === modified file 'libubuntu-app-launch/jobs-systemd.cpp' |
2095 | --- libubuntu-app-launch/jobs-systemd.cpp 2017-03-21 03:26:39 +0000 |
2096 | +++ libubuntu-app-launch/jobs-systemd.cpp 2017-03-21 03:26:40 +0000 |
2097 | @@ -19,9 +19,9 @@ |
2098 | |
2099 | #include "jobs-systemd.h" |
2100 | #include "application-impl-base.h" |
2101 | -#include "helpers.h" |
2102 | #include "registry-impl.h" |
2103 | #include "second-exec-core.h" |
2104 | +#include "utils.h" |
2105 | |
2106 | extern "C" { |
2107 | #include "ubuntu-app-launch-trace.h" |
2108 | @@ -587,6 +587,9 @@ |
2109 | if (appId.empty()) |
2110 | return {}; |
2111 | |
2112 | + bool isApplication = |
2113 | + std::find(allApplicationJobs_.begin(), allApplicationJobs_.end(), job) != allApplicationJobs_.end(); |
2114 | + |
2115 | auto registry = registry_.lock(); |
2116 | return registry->impl->thread.executeOnThread<std::shared_ptr<instance::SystemD>>( |
2117 | [&]() -> std::shared_ptr<instance::SystemD> { |
2118 | @@ -602,10 +605,15 @@ |
2119 | timeout = 0; |
2120 | } |
2121 | |
2122 | - auto handshake = starting_handshake_start(appIdStr.c_str(), instance.c_str(), timeout); |
2123 | - if (handshake == nullptr) |
2124 | + handshake_t* handshake{nullptr}; |
2125 | + |
2126 | + if (isApplication) |
2127 | { |
2128 | - g_warning("Unable to setup starting handshake"); |
2129 | + handshake = starting_handshake_start(appIdStr.c_str(), instance.c_str(), timeout); |
2130 | + if (handshake == nullptr) |
2131 | + { |
2132 | + g_warning("Unable to setup starting handshake"); |
2133 | + } |
2134 | } |
2135 | |
2136 | /* Figure out the unit name for the job */ |
2137 | @@ -903,8 +911,7 @@ |
2138 | } |
2139 | |
2140 | /* TODO: Application job names */ |
2141 | -const std::regex unitNaming{ |
2142 | - "^ubuntu\\-app\\-launch\\-(application\\-(?:click|legacy|snap))\\-(.*)\\-([0-9]*)\\.service$"}; |
2143 | +const std::regex unitNaming{"^ubuntu\\-app\\-launch\\-\\-(.*)\\-\\-(.*)\\-\\-([0-9]*)\\.service$"}; |
2144 | |
2145 | SystemD::UnitInfo SystemD::parseUnit(const std::string& unit) const |
2146 | { |
2147 | @@ -919,7 +926,7 @@ |
2148 | |
2149 | std::string SystemD::unitName(const SystemD::UnitInfo& info) const |
2150 | { |
2151 | - return std::string{"ubuntu-app-launch-"} + info.job + "-" + info.appid + "-" + info.inst + ".service"; |
2152 | + return std::string{"ubuntu-app-launch--"} + info.job + "--" + info.appid + "--" + info.inst + ".service"; |
2153 | } |
2154 | |
2155 | std::string SystemD::unitPath(const SystemD::UnitInfo& info) |
2156 | @@ -1347,6 +1354,11 @@ |
2157 | auto cancel = registry->impl->thread.getCancellable(); |
2158 | |
2159 | registry->impl->thread.executeOnThread([bus, unitname, cancel] { |
2160 | + if (g_cancellable_is_cancelled(cancel.get())) |
2161 | + { |
2162 | + return; |
2163 | + } |
2164 | + |
2165 | g_dbus_connection_call(bus.get(), /* user bus */ |
2166 | SYSTEMD_DBUS_ADDRESS, /* bus name */ |
2167 | SYSTEMD_DBUS_PATH_MANAGER, /* path */ |
2168 | |
2169 | === modified file 'libubuntu-app-launch/registry-impl.cpp' |
2170 | --- libubuntu-app-launch/registry-impl.cpp 2017-03-21 03:26:39 +0000 |
2171 | +++ libubuntu-app-launch/registry-impl.cpp 2017-03-21 03:26:40 +0000 |
2172 | @@ -28,11 +28,13 @@ |
2173 | { |
2174 | |
2175 | Registry::Impl::Impl(Registry* registry) |
2176 | + : Impl(registry, app_store::Base::allAppStores()) |
2177 | +{ |
2178 | +} |
2179 | + |
2180 | +Registry::Impl::Impl(Registry* registry, std::list<std::shared_ptr<app_store::Base>> appStores) |
2181 | : thread([]() {}, |
2182 | [this]() { |
2183 | - _clickUser.reset(); |
2184 | - _clickDB.reset(); |
2185 | - |
2186 | zgLog_.reset(); |
2187 | jobs.reset(); |
2188 | |
2189 | @@ -42,7 +44,7 @@ |
2190 | }) |
2191 | , _registry{registry} |
2192 | , _iconFinders() |
2193 | - , _appStores(app_store::Base::allAppStores()) |
2194 | + , _appStores(appStores) |
2195 | { |
2196 | auto cancel = thread.getCancellable(); |
2197 | _dbus = thread.executeOnThread<std::shared_ptr<GDBusConnection>>([cancel]() { |
2198 | @@ -62,52 +64,6 @@ |
2199 | } |
2200 | } |
2201 | |
2202 | -void Registry::Impl::initClick() |
2203 | -{ |
2204 | - if (_clickDB && _clickUser) |
2205 | - { |
2206 | - return; |
2207 | - } |
2208 | - |
2209 | - auto init = thread.executeOnThread<bool>([this]() { |
2210 | - GError* error = nullptr; |
2211 | - |
2212 | - if (!_clickDB) |
2213 | - { |
2214 | - _clickDB = std::shared_ptr<ClickDB>(click_db_new(), [](ClickDB* db) { g_clear_object(&db); }); |
2215 | - /* If TEST_CLICK_DB is unset, this reads the system database. */ |
2216 | - click_db_read(_clickDB.get(), g_getenv("TEST_CLICK_DB"), &error); |
2217 | - |
2218 | - if (error != nullptr) |
2219 | - { |
2220 | - auto perror = std::shared_ptr<GError>(error, [](GError* error) { g_error_free(error); }); |
2221 | - throw std::runtime_error(perror->message); |
2222 | - } |
2223 | - } |
2224 | - |
2225 | - if (!_clickUser) |
2226 | - { |
2227 | - _clickUser = |
2228 | - std::shared_ptr<ClickUser>(click_user_new_for_user(_clickDB.get(), g_getenv("TEST_CLICK_USER"), &error), |
2229 | - [](ClickUser* user) { g_clear_object(&user); }); |
2230 | - |
2231 | - if (error != nullptr) |
2232 | - { |
2233 | - auto perror = std::shared_ptr<GError>(error, [](GError* error) { g_error_free(error); }); |
2234 | - throw std::runtime_error(perror->message); |
2235 | - } |
2236 | - } |
2237 | - |
2238 | - g_debug("Initialized Click DB"); |
2239 | - return true; |
2240 | - }); |
2241 | - |
2242 | - if (!init) |
2243 | - { |
2244 | - throw std::runtime_error("Unable to initialize the Click Database"); |
2245 | - } |
2246 | -} |
2247 | - |
2248 | /** Helper function for printing JSON objects to debug output */ |
2249 | std::string Registry::Impl::printJson(std::shared_ptr<JsonObject> jsonobj) |
2250 | { |
2251 | @@ -133,89 +89,8 @@ |
2252 | return retval; |
2253 | } |
2254 | |
2255 | -std::shared_ptr<JsonObject> Registry::Impl::getClickManifest(const std::string& package) |
2256 | -{ |
2257 | - initClick(); |
2258 | - |
2259 | - auto retval = thread.executeOnThread<std::shared_ptr<JsonObject>>([this, package]() { |
2260 | - GError* error = nullptr; |
2261 | - auto mani = click_user_get_manifest(_clickUser.get(), package.c_str(), &error); |
2262 | - |
2263 | - if (error != nullptr) |
2264 | - { |
2265 | - auto perror = std::shared_ptr<GError>(error, [](GError* error) { g_error_free(error); }); |
2266 | - g_debug("Error parsing manifest for package '%s': %s", package.c_str(), perror->message); |
2267 | - return std::shared_ptr<JsonObject>(); |
2268 | - } |
2269 | - |
2270 | - auto node = json_node_alloc(); |
2271 | - json_node_init_object(node, mani); |
2272 | - json_object_unref(mani); |
2273 | - |
2274 | - auto retval = std::shared_ptr<JsonObject>(json_node_dup_object(node), json_object_unref); |
2275 | - |
2276 | - json_node_free(node); |
2277 | - |
2278 | - return retval; |
2279 | - }); |
2280 | - |
2281 | - if (!retval) |
2282 | - throw std::runtime_error("Unable to get Click manifest for package: " + package); |
2283 | - |
2284 | - return retval; |
2285 | -} |
2286 | - |
2287 | -std::list<AppID::Package> Registry::Impl::getClickPackages() |
2288 | -{ |
2289 | - initClick(); |
2290 | - |
2291 | - return thread.executeOnThread<std::list<AppID::Package>>([this]() { |
2292 | - GError* error = nullptr; |
2293 | - GList* pkgs = click_user_get_package_names(_clickUser.get(), &error); |
2294 | - |
2295 | - if (error != nullptr) |
2296 | - { |
2297 | - auto perror = std::shared_ptr<GError>(error, [](GError* error) { g_error_free(error); }); |
2298 | - throw std::runtime_error(perror->message); |
2299 | - } |
2300 | - |
2301 | - std::list<AppID::Package> list; |
2302 | - for (GList* item = pkgs; item != nullptr; item = g_list_next(item)) |
2303 | - { |
2304 | - auto pkgobj = static_cast<gchar*>(item->data); |
2305 | - if (pkgobj) |
2306 | - { |
2307 | - list.emplace_back(AppID::Package::from_raw(pkgobj)); |
2308 | - } |
2309 | - } |
2310 | - |
2311 | - g_list_free_full(pkgs, g_free); |
2312 | - return list; |
2313 | - }); |
2314 | -} |
2315 | - |
2316 | -std::string Registry::Impl::getClickDir(const std::string& package) |
2317 | -{ |
2318 | - initClick(); |
2319 | - |
2320 | - return thread.executeOnThread<std::string>([this, package]() { |
2321 | - GError* error = nullptr; |
2322 | - auto dir = click_user_get_path(_clickUser.get(), package.c_str(), &error); |
2323 | - |
2324 | - if (error != nullptr) |
2325 | - { |
2326 | - auto perror = std::shared_ptr<GError>(error, [](GError* error) { g_error_free(error); }); |
2327 | - throw std::runtime_error(perror->message); |
2328 | - } |
2329 | - |
2330 | - std::string cppdir(dir); |
2331 | - g_free(dir); |
2332 | - return cppdir; |
2333 | - }); |
2334 | -} |
2335 | - |
2336 | -/** Send an event to Zeitgeist using the registry thread so that |
2337 | - the callback comes back in the right place. */ |
2338 | +/** Send an event to Zietgeist using the registry thread so that |
2339 | + the callback comes back in the right place. */ |
2340 | void Registry::Impl::zgSendEvent(AppID appid, const std::string& eventtype) |
2341 | { |
2342 | thread.executeOnThread([this, appid, eventtype] { |
2343 | |
2344 | === modified file 'libubuntu-app-launch/registry-impl.h' |
2345 | --- libubuntu-app-launch/registry-impl.h 2017-03-21 03:26:39 +0000 |
2346 | +++ libubuntu-app-launch/registry-impl.h 2017-03-21 03:26:40 +0000 |
2347 | @@ -23,7 +23,6 @@ |
2348 | #include "jobs-base.h" |
2349 | #include "registry.h" |
2350 | #include "snapd-info.h" |
2351 | -#include <click.h> |
2352 | #include <gio/gio.h> |
2353 | #include <json-glib/json-glib.h> |
2354 | #include <map> |
2355 | @@ -47,15 +46,13 @@ |
2356 | { |
2357 | public: |
2358 | Impl(Registry* registry); |
2359 | + Impl(Registry* registry, std::list<std::shared_ptr<app_store::Base>> appStores); |
2360 | + |
2361 | virtual ~Impl() |
2362 | { |
2363 | thread.quit(); |
2364 | } |
2365 | |
2366 | - std::shared_ptr<JsonObject> getClickManifest(const std::string& package); |
2367 | - std::list<AppID::Package> getClickPackages(); |
2368 | - std::string getClickDir(const std::string& package); |
2369 | - |
2370 | static void setManager(const std::shared_ptr<Registry::Manager>& manager, |
2371 | const std::shared_ptr<Registry>& registry); |
2372 | void clearManager(); |
2373 | @@ -66,10 +63,8 @@ |
2374 | /** DBus shared connection for the session bus */ |
2375 | std::shared_ptr<GDBusConnection> _dbus; |
2376 | |
2377 | -#ifdef ENABLE_SNAPPY |
2378 | /** Snapd information object */ |
2379 | snapd::Info snapdInfo; |
2380 | -#endif |
2381 | |
2382 | std::shared_ptr<jobs::manager::Base> jobs; |
2383 | |
2384 | @@ -105,14 +100,14 @@ |
2385 | return _appStores; |
2386 | } |
2387 | |
2388 | + void setAppStores(std::list<std::shared_ptr<app_store::Base>>& newlist) |
2389 | + { |
2390 | + _appStores = newlist; |
2391 | + } |
2392 | + |
2393 | private: |
2394 | Registry* _registry; /**< The Registry that we're spawned from */ |
2395 | |
2396 | - std::shared_ptr<ClickDB> _clickDB; /**< Shared instance of the Click Database */ |
2397 | - std::shared_ptr<ClickUser> _clickUser; /**< Click database filtered by the current user */ |
2398 | - |
2399 | - void initClick(); |
2400 | - |
2401 | /** Shared instance of the Zeitgeist Log */ |
2402 | std::shared_ptr<ZeitgeistLog> zgLog_; |
2403 | |
2404 | |
2405 | === modified file 'libubuntu-app-launch/second-exec-core.c' |
2406 | --- libubuntu-app-launch/second-exec-core.c 2017-03-21 03:26:39 +0000 |
2407 | +++ libubuntu-app-launch/second-exec-core.c 2017-03-21 03:26:40 +0000 |
2408 | @@ -19,7 +19,7 @@ |
2409 | |
2410 | #include <gio/gio.h> |
2411 | #include "libubuntu-app-launch/ubuntu-app-launch.h" |
2412 | -#include "helpers.h" |
2413 | +#include "utils.h" |
2414 | #include "second-exec-core.h" |
2415 | #include "ubuntu-app-launch-trace.h" |
2416 | #include "ual-tracepoint.h" |
2417 | |
2418 | === modified file 'libubuntu-app-launch/type-tagger.h' |
2419 | --- libubuntu-app-launch/type-tagger.h 2016-06-09 14:55:34 +0000 |
2420 | +++ libubuntu-app-launch/type-tagger.h 2017-03-21 03:26:40 +0000 |
2421 | @@ -32,6 +32,14 @@ |
2422 | { |
2423 | return _value; |
2424 | } |
2425 | + bool operator==(const TypeTagger<Tag, T>& b) const |
2426 | + { |
2427 | + return _value == b._value; |
2428 | + } |
2429 | + bool operator==(const T& b) const |
2430 | + { |
2431 | + return _value == b; |
2432 | + } |
2433 | ~TypeTagger() |
2434 | { |
2435 | } |
2436 | |
2437 | === renamed file 'ual-tracepoint.h' => 'libubuntu-app-launch/ual-tracepoint.h' |
2438 | === modified file 'libubuntu-app-launch/ubuntu-app-launch.cpp' |
2439 | --- libubuntu-app-launch/ubuntu-app-launch.cpp 2017-03-21 03:26:39 +0000 |
2440 | +++ libubuntu-app-launch/ubuntu-app-launch.cpp 2017-03-21 03:26:40 +0000 |
2441 | @@ -28,7 +28,7 @@ |
2442 | #include <libwhoopsie/recoverable-problem.h> |
2443 | |
2444 | #include "ubuntu-app-launch-trace.h" |
2445 | -#include "helpers.h" |
2446 | +#include "utils.h" |
2447 | #include "ual-tracepoint.h" |
2448 | #include "proxy-socket-demangler.h" |
2449 | } |
2450 | @@ -423,11 +423,12 @@ |
2451 | ubuntu_app_launch_observer_add_app_failed (UbuntuAppLaunchAppFailedObserver observer, gpointer user_data) |
2452 | { |
2453 | auto context = std::shared_ptr<GMainContext>(g_main_context_ref_thread_default(), [](GMainContext * context) { g_clear_pointer(&context, g_main_context_unref); }); |
2454 | + auto reg = ubuntu::app_launch::Registry::getDefault(); |
2455 | |
2456 | appFailedObservers.emplace(std::make_pair( |
2457 | std::make_pair(observer, user_data), |
2458 | core::ScopedConnection( |
2459 | - ubuntu::app_launch::Registry::appFailed().connect([context, observer, user_data](std::shared_ptr<ubuntu::app_launch::Application> app, std::shared_ptr<ubuntu::app_launch::Application::Instance> instance, ubuntu::app_launch::Registry::FailureType type) { |
2460 | + ubuntu::app_launch::Registry::appFailed(reg).connect([context, observer, user_data](std::shared_ptr<ubuntu::app_launch::Application> app, std::shared_ptr<ubuntu::app_launch::Application::Instance> instance, ubuntu::app_launch::Registry::FailureType type) { |
2461 | std::string appid = app->appId(); |
2462 | executeOnContext(context, [appid, type, observer, user_data]() { |
2463 | UbuntuAppLaunchAppFailed ctype{UBUNTU_APP_LAUNCH_APP_FAILED_CRASH}; |
2464 | @@ -524,7 +525,8 @@ |
2465 | } |
2466 | |
2467 | return (gchar **)g_array_free(apps, FALSE); |
2468 | - } catch (...) { |
2469 | + } catch (const std::exception& e) { |
2470 | + g_debug("Unable to list applications: %s", e.what()); |
2471 | return nullptr; |
2472 | } |
2473 | } |
2474 | @@ -539,7 +541,8 @@ |
2475 | auto appId = ubuntu::app_launch::AppID::find(appid); |
2476 | auto app = ubuntu::app_launch::Application::create(appId, registry); |
2477 | return app->instances().at(0)->primaryPid(); |
2478 | - } catch (...) { |
2479 | + } catch (const std::exception& e) { |
2480 | + g_debug("Unable to get primary pid: %s", e.what()); |
2481 | return 0; |
2482 | } |
2483 | } |
2484 | @@ -637,6 +640,7 @@ |
2485 | |
2486 | auto appid = ubuntu::app_launch::AppID::discover(package, appname, version); |
2487 | if (appid.empty()) { |
2488 | + g_debug("Triplet lookup for '%s' '%s' '%s' returned empty", pkg, app, ver); |
2489 | return nullptr; |
2490 | } |
2491 | |
2492 | @@ -666,10 +670,10 @@ |
2493 | throw std::runtime_error{"Empty instance"}; |
2494 | } |
2495 | |
2496 | - return true; |
2497 | + return TRUE; |
2498 | } catch (std::runtime_error &e) { |
2499 | g_warning("Unable to launch helper of type '%s' id '%s': %s", type, appid, e.what()); |
2500 | - return false; |
2501 | + return FALSE; |
2502 | } |
2503 | } |
2504 | |
2505 | @@ -954,3 +958,9 @@ |
2506 | } |
2507 | } |
2508 | |
2509 | +gboolean |
2510 | +ubuntu_app_launch_application_info (const gchar * appid, gchar ** appdir, gchar ** appdesktop) |
2511 | +{ |
2512 | + /* TODO: Remove next ABI break */ |
2513 | + return FALSE; |
2514 | +} |
2515 | |
2516 | === renamed file 'helpers-shared.c' => 'libubuntu-app-launch/utils-shared.c' |
2517 | --- helpers-shared.c 2016-11-09 23:13:38 +0000 |
2518 | +++ libubuntu-app-launch/utils-shared.c 2017-03-21 03:26:40 +0000 |
2519 | @@ -17,7 +17,7 @@ |
2520 | * Ted Gould <ted.gould@canonical.com> |
2521 | */ |
2522 | |
2523 | -#include "helpers.h" |
2524 | +#include "utils.h" |
2525 | #include <gio/gio.h> |
2526 | #include <cgmanager/cgmanager.h> |
2527 | |
2528 | |
2529 | === renamed file 'helpers.c' => 'libubuntu-app-launch/utils.c' |
2530 | --- helpers.c 2017-03-21 03:26:39 +0000 |
2531 | +++ libubuntu-app-launch/utils.c 2017-03-21 03:26:40 +0000 |
2532 | @@ -18,8 +18,7 @@ |
2533 | */ |
2534 | |
2535 | #include <json-glib/json-glib.h> |
2536 | -#include <click.h> |
2537 | -#include "helpers.h" |
2538 | +#include "utils.h" |
2539 | |
2540 | /* Take an app ID and validate it and then break it up |
2541 | and spit it out. These are newly allocated strings */ |
2542 | @@ -56,106 +55,6 @@ |
2543 | return TRUE; |
2544 | } |
2545 | |
2546 | -/* Take a manifest, parse it, find the application and |
2547 | - and then return the path to the desktop file */ |
2548 | -gchar * |
2549 | -manifest_to_desktop (const gchar * app_dir, const gchar * app_id) |
2550 | -{ |
2551 | - gchar * package = NULL; |
2552 | - gchar * application = NULL; |
2553 | - gchar * version = NULL; |
2554 | - ClickDB * db = NULL; |
2555 | - ClickUser * user = NULL; |
2556 | - JsonObject * manifest = NULL; |
2557 | - gchar * desktoppath = NULL; |
2558 | - GError * error = NULL; |
2559 | - |
2560 | - if (!app_id_to_triplet(app_id, &package, &application, &version)) { |
2561 | - g_warning("Unable to parse triplet: %s", app_id); |
2562 | - return NULL; |
2563 | - } |
2564 | - |
2565 | - db = click_db_new(); |
2566 | - /* If TEST_CLICK_DB is unset, this reads the system database. */ |
2567 | - click_db_read(db, g_getenv("TEST_CLICK_DB"), &error); |
2568 | - if (error != NULL) { |
2569 | - g_warning("Unable to read Click database: %s", error->message); |
2570 | - goto manifest_out; |
2571 | - } |
2572 | - /* If TEST_CLICK_USER is unset, this uses the current user name. */ |
2573 | - user = click_user_new_for_user(db, g_getenv("TEST_CLICK_USER"), &error); |
2574 | - if (error != NULL) { |
2575 | - g_warning("Unable to read Click database: %s", error->message); |
2576 | - goto manifest_out; |
2577 | - } |
2578 | - manifest = click_user_get_manifest(user, package, &error); |
2579 | - if (error != NULL) { |
2580 | - g_warning("Unable to get manifest for '%s': %s", package, error->message); |
2581 | - goto manifest_out; |
2582 | - } |
2583 | - |
2584 | - if (!json_object_has_member(manifest, "version")) { |
2585 | - g_warning("Manifest '%s' doesn't have a version", package); |
2586 | - goto manifest_out; |
2587 | - } |
2588 | - |
2589 | - if (g_strcmp0(json_object_get_string_member(manifest, "version"), version) != 0) { |
2590 | - g_warning("Manifest '%s' version '%s' doesn't match AppID version '%s'", package, json_object_get_string_member(manifest, "version"), version); |
2591 | - goto manifest_out; |
2592 | - } |
2593 | - |
2594 | - if (!json_object_has_member(manifest, "hooks")) { |
2595 | - g_warning("Manifest '%s' doesn't have an hooks section", package); |
2596 | - goto manifest_out; |
2597 | - } |
2598 | - |
2599 | - JsonObject * appsobj = json_object_get_object_member(manifest, "hooks"); |
2600 | - if (appsobj == NULL) { |
2601 | - g_warning("Manifest '%s' has an hooks section that is not a JSON object", package); |
2602 | - goto manifest_out; |
2603 | - } |
2604 | - |
2605 | - if (!json_object_has_member(appsobj, application)) { |
2606 | - g_warning("Manifest '%s' doesn't have the application '%s' defined", package, application); |
2607 | - goto manifest_out; |
2608 | - } |
2609 | - |
2610 | - JsonObject * appobj = json_object_get_object_member(appsobj, application); |
2611 | - if (appobj == NULL) { |
2612 | - g_warning("Manifest '%s' has a definition for application '%s' that is not an object", package, application); |
2613 | - goto manifest_out; |
2614 | - } |
2615 | - |
2616 | - gchar * filename = NULL; |
2617 | - if (json_object_has_member(appobj, "desktop")) { |
2618 | - filename = g_strdup(json_object_get_string_member(appobj, "desktop")); |
2619 | - } else { |
2620 | - filename = g_strdup_printf("%s.desktop", application); |
2621 | - } |
2622 | - |
2623 | - desktoppath = g_build_filename(app_dir, filename, NULL); |
2624 | - g_free(filename); |
2625 | - |
2626 | - if (!g_file_test(desktoppath, G_FILE_TEST_EXISTS)) { |
2627 | - g_warning("Application desktop file '%s' doesn't exist", desktoppath); |
2628 | - g_free(desktoppath); |
2629 | - desktoppath = NULL; |
2630 | - } |
2631 | - |
2632 | -manifest_out: |
2633 | - if (error != NULL) |
2634 | - g_error_free(error); |
2635 | - if (manifest != NULL) |
2636 | - json_object_unref(manifest); |
2637 | - g_clear_object(&user); |
2638 | - g_clear_object(&db); |
2639 | - g_free(package); |
2640 | - g_free(application); |
2641 | - g_free(version); |
2642 | - |
2643 | - return desktoppath; |
2644 | -} |
2645 | - |
2646 | /* Take a desktop file, make sure that it makes sense and |
2647 | then return the exec line */ |
2648 | gchar * |
2649 | |
2650 | === renamed file 'helpers.h' => 'libubuntu-app-launch/utils.h' |
2651 | --- helpers.h 2017-03-21 03:26:39 +0000 |
2652 | +++ libubuntu-app-launch/utils.h 2017-03-21 03:26:40 +0000 |
2653 | @@ -25,8 +25,6 @@ |
2654 | gchar ** package, |
2655 | gchar ** application, |
2656 | gchar ** version); |
2657 | -gchar * manifest_to_desktop (const gchar * app_dir, |
2658 | - const gchar * app_id); |
2659 | gchar * desktop_to_exec (GKeyFile * desktop_file, |
2660 | const gchar * from); |
2661 | GArray * desktop_exec_parse (const gchar * execline, |
2662 | |
2663 | === modified file 'tests/CMakeLists.txt' |
2664 | --- tests/CMakeLists.txt 2017-03-21 03:26:39 +0000 |
2665 | +++ tests/CMakeLists.txt 2017-03-21 03:26:40 +0000 |
2666 | @@ -1,13 +1,5 @@ |
2667 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") |
2668 | |
2669 | -configure_file ("click-db-dir/test.conf.in" "${CMAKE_CURRENT_BINARY_DIR}/click-db-dir/test.conf" @ONLY) |
2670 | -set_directory_properties (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/click-db-dir/test.conf") |
2671 | - |
2672 | -if(CURL_FOUND) |
2673 | -add_definitions ( -DENABLE_SNAPPY=1 ) |
2674 | -endif() |
2675 | - |
2676 | - |
2677 | # Google Test |
2678 | |
2679 | find_package(GMock) |
2680 | @@ -17,14 +9,14 @@ |
2681 | add_executable (helper-test helper-test.cc) |
2682 | add_definitions ( -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ) |
2683 | add_definitions ( -DCMAKE_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}" ) |
2684 | -target_link_libraries (helper-test helpers gtest_main ${GTEST_MAIN_LIBRARIES} ${DBUSTEST_LIBRARIES}) |
2685 | +target_link_libraries (helper-test launcher-static gtest_main ${GTEST_MAIN_LIBRARIES} ${DBUSTEST_LIBRARIES}) |
2686 | |
2687 | add_test (helper-test helper-test) |
2688 | |
2689 | # Helper test |
2690 | |
2691 | add_executable (helper-handshake-test helper-handshake-test.cc) |
2692 | -target_link_libraries (helper-handshake-test helpers gtest_main ${GTEST_MAIN_LIBRARIES}) |
2693 | +target_link_libraries (helper-handshake-test launcher-static gtest_main ${GTEST_MAIN_LIBRARIES}) |
2694 | |
2695 | add_test (helper-handshake-test helper-handshake-test) |
2696 | |
2697 | @@ -33,7 +25,7 @@ |
2698 | include_directories("${CMAKE_SOURCE_DIR}/libubuntu-app-launch") |
2699 | add_definitions ( -DSPEW_UTILITY="${CMAKE_CURRENT_BINARY_DIR}/data-spew" ) |
2700 | add_definitions ( -DSESSION_TEMP_FILE="${CMAKE_CURRENT_BINARY_DIR}/libual-test-session-start-temp" ) |
2701 | -add_definitions ( -DSOCKET_DEMANGLER="${CMAKE_BINARY_DIR}/socket-demangler" ) |
2702 | +add_definitions ( -DSOCKET_DEMANGLER="${CMAKE_BINARY_DIR}/utils/socket-demangler" ) |
2703 | add_definitions ( -DSOCKET_DEMANGLER_INSTALL="${pkglibexecdir}/socket-demangler" ) |
2704 | add_definitions ( -DSOCKET_TOOL="${CMAKE_CURRENT_BINARY_DIR}/socket-tool" ) |
2705 | add_definitions ( -DSNAP_BASEDIR="${CMAKE_CURRENT_SOURCE_DIR}/snap-basedir" ) |
2706 | @@ -46,7 +38,7 @@ |
2707 | add_executable (libual-cpp-test |
2708 | libual-cpp-test.cc |
2709 | mir-mock.cpp) |
2710 | -target_link_libraries (libual-cpp-test gtest_main ${GTEST_MAIN_LIBRARIES} ${LIBUPSTART_LIBRARIES} ${DBUSTEST_LIBRARIES} launcher-static) |
2711 | +target_link_libraries (libual-cpp-test gtest_main ${GMOCK_LIBRARIES} ${LIBUPSTART_LIBRARIES} ${DBUSTEST_LIBRARIES} launcher-static) |
2712 | |
2713 | add_executable (data-spew |
2714 | data-spew.c) |
2715 | @@ -122,12 +114,6 @@ |
2716 | |
2717 | file(COPY data DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) |
2718 | |
2719 | -# Desktop Hook Test |
2720 | - |
2721 | -configure_file ("click-desktop-hook-db/test.conf.in" "${CMAKE_CURRENT_BINARY_DIR}/click-desktop-hook-db/test.conf" @ONLY) |
2722 | -configure_file ("desktop-hook-test.sh.in" "${CMAKE_CURRENT_BINARY_DIR}/desktop-hook-test.sh" @ONLY) |
2723 | -add_test (desktop-hook-test desktop-hook-test.sh) |
2724 | - |
2725 | # XMir helper Test |
2726 | |
2727 | configure_file ("xmir-helper-test.in" "${CMAKE_CURRENT_BINARY_DIR}/xmir-helper-test" @ONLY) |
2728 | @@ -144,6 +130,7 @@ |
2729 | COMMAND clang-format -i -style=file |
2730 | application-info-desktop.cpp |
2731 | libual-cpp-test.cc |
2732 | + libual-test.cc |
2733 | list-apps.cpp |
2734 | eventually-fixture.h |
2735 | info-watcher-zg.cpp |
2736 | |
2737 | === modified file 'tests/application-info-desktop.cpp' |
2738 | --- tests/application-info-desktop.cpp 2017-02-09 19:43:14 +0000 |
2739 | +++ tests/application-info-desktop.cpp 2017-03-21 03:26:40 +0000 |
2740 | @@ -408,10 +408,11 @@ |
2741 | .WillOnce(testing::Return(ubuntu::app_launch::Application::Info::Popularity::from_raw(5u))); |
2742 | |
2743 | auto keyfile = defaultKeyfile(); |
2744 | - EXPECT_EQ(5u, ubuntu::app_launch::app_info::Desktop(simpleAppID(), keyfile, "/", {}, |
2745 | - ubuntu::app_launch::app_info::DesktopFlags::NONE, registry()) |
2746 | - .popularity() |
2747 | - .value()); |
2748 | + EXPECT_EQ(5u, |
2749 | + ubuntu::app_launch::app_info::Desktop(simpleAppID(), keyfile, "/", {}, |
2750 | + ubuntu::app_launch::app_info::DesktopFlags::NONE, registry()) |
2751 | + .popularity() |
2752 | + .value()); |
2753 | } |
2754 | |
2755 | } // anonymous namespace |
2756 | |
2757 | === modified file 'tests/applications/foo.desktop' |
2758 | --- tests/applications/foo.desktop 2017-01-10 18:41:25 +0000 |
2759 | +++ tests/applications/foo.desktop 2017-03-21 03:26:40 +0000 |
2760 | @@ -1,7 +1,7 @@ |
2761 | [Desktop Entry] |
2762 | Name=Foo |
2763 | Type=Application |
2764 | -Exec=foo |
2765 | +Exec=foo %U |
2766 | NoDisplay=false |
2767 | Hidden=false |
2768 | Terminal=false |
2769 | |
2770 | === removed directory 'tests/click-app-dir' |
2771 | === removed directory 'tests/click-app-dir/.click' |
2772 | === removed directory 'tests/click-app-dir/.click/info' |
2773 | === removed file 'tests/click-app-dir/.click/info/chatter.robert-ancell.manifest' |
2774 | --- tests/click-app-dir/.click/info/chatter.robert-ancell.manifest 2016-08-23 14:52:49 +0000 |
2775 | +++ tests/click-app-dir/.click/info/chatter.robert-ancell.manifest 1970-01-01 00:00:00 +0000 |
2776 | @@ -1,8 +0,0 @@ |
2777 | -{ |
2778 | - "version": "2", |
2779 | - "hooks": { |
2780 | - "chatter": { |
2781 | - "desktop": "chatter.desktop" |
2782 | - } |
2783 | - } |
2784 | -} |
2785 | |
2786 | === removed file 'tests/click-app-dir/.click/info/com.test.bad-version.manifest' |
2787 | --- tests/click-app-dir/.click/info/com.test.bad-version.manifest 2013-09-24 03:48:52 +0000 |
2788 | +++ tests/click-app-dir/.click/info/com.test.bad-version.manifest 1970-01-01 00:00:00 +0000 |
2789 | @@ -1,8 +0,0 @@ |
2790 | -{ |
2791 | - "version": "4.5.6", |
2792 | - "hooks": { |
2793 | - "application": { |
2794 | - "desktop": "application.desktop" |
2795 | - } |
2796 | - } |
2797 | -} |
2798 | |
2799 | === removed file 'tests/click-app-dir/.click/info/com.test.good.manifest' |
2800 | --- tests/click-app-dir/.click/info/com.test.good.manifest 2014-08-25 20:01:18 +0000 |
2801 | +++ tests/click-app-dir/.click/info/com.test.good.manifest 1970-01-01 00:00:00 +0000 |
2802 | @@ -1,8 +0,0 @@ |
2803 | -{ |
2804 | - "version": "1.2.3", |
2805 | - "hooks": { |
2806 | - "application": { |
2807 | - "desktop": "application.desktop" |
2808 | - } |
2809 | - } |
2810 | -} |
2811 | |
2812 | === removed file 'tests/click-app-dir/.click/info/com.test.mir.manifest' |
2813 | --- tests/click-app-dir/.click/info/com.test.mir.manifest 2015-07-02 02:38:56 +0000 |
2814 | +++ tests/click-app-dir/.click/info/com.test.mir.manifest 1970-01-01 00:00:00 +0000 |
2815 | @@ -1,11 +0,0 @@ |
2816 | -{ |
2817 | - "version": "1", |
2818 | - "hooks": { |
2819 | - "mir": { |
2820 | - "desktop": "xmir.desktop" |
2821 | - }, |
2822 | - "nomir": { |
2823 | - "desktop": "noxmir.desktop" |
2824 | - } |
2825 | - } |
2826 | -} |
2827 | |
2828 | === removed file 'tests/click-app-dir/.click/info/com.test.multiple.manifest' |
2829 | --- tests/click-app-dir/.click/info/com.test.multiple.manifest 2014-01-29 02:19:41 +0000 |
2830 | +++ tests/click-app-dir/.click/info/com.test.multiple.manifest 1970-01-01 00:00:00 +0000 |
2831 | @@ -1,20 +0,0 @@ |
2832 | -{ |
2833 | - "version": "1.2.3", |
2834 | - "hooks": { |
2835 | - "first": { |
2836 | - "desktop": "application.desktop" |
2837 | - }, |
2838 | - "second": { |
2839 | - "desktop": "application.desktop" |
2840 | - }, |
2841 | - "third": { |
2842 | - "desktop": "application.desktop" |
2843 | - }, |
2844 | - "fourth": { |
2845 | - "desktop": "application.desktop" |
2846 | - }, |
2847 | - "fifth": { |
2848 | - "desktop": "application.desktop" |
2849 | - } |
2850 | - } |
2851 | -} |
2852 | |
2853 | === removed file 'tests/click-app-dir/.click/info/com.test.no-app.manifest' |
2854 | --- tests/click-app-dir/.click/info/com.test.no-app.manifest 2013-09-24 03:48:52 +0000 |
2855 | +++ tests/click-app-dir/.click/info/com.test.no-app.manifest 1970-01-01 00:00:00 +0000 |
2856 | @@ -1,8 +0,0 @@ |
2857 | -{ |
2858 | - "version": "1.2.3", |
2859 | - "hooks": { |
2860 | - "no-application": { |
2861 | - "desktop": "application.desktop" |
2862 | - } |
2863 | - } |
2864 | -} |
2865 | |
2866 | === removed file 'tests/click-app-dir/.click/info/com.test.no-hooks.manifest' |
2867 | --- tests/click-app-dir/.click/info/com.test.no-hooks.manifest 2013-09-24 03:48:52 +0000 |
2868 | +++ tests/click-app-dir/.click/info/com.test.no-hooks.manifest 1970-01-01 00:00:00 +0000 |
2869 | @@ -1,8 +0,0 @@ |
2870 | -{ |
2871 | - "version": "1.2.3", |
2872 | - "hookie": { |
2873 | - "application": { |
2874 | - "desktop": "application.desktop" |
2875 | - } |
2876 | - } |
2877 | -} |
2878 | |
2879 | === removed file 'tests/click-app-dir/.click/info/com.test.no-json.manifest' |
2880 | --- tests/click-app-dir/.click/info/com.test.no-json.manifest 2013-09-24 03:48:52 +0000 |
2881 | +++ tests/click-app-dir/.click/info/com.test.no-json.manifest 1970-01-01 00:00:00 +0000 |
2882 | @@ -1,5 +0,0 @@ |
2883 | -<xmlFile> |
2884 | - <moreData> |
2885 | - Lovin' some data |
2886 | - </moreData> |
2887 | -</xmlFile> |
2888 | |
2889 | === removed file 'tests/click-app-dir/.click/info/com.test.no-object.manifest' |
2890 | --- tests/click-app-dir/.click/info/com.test.no-object.manifest 2013-09-24 03:48:52 +0000 |
2891 | +++ tests/click-app-dir/.click/info/com.test.no-object.manifest 1970-01-01 00:00:00 +0000 |
2892 | @@ -1,6 +0,0 @@ |
2893 | -[ |
2894 | - "foo", |
2895 | - "bar", |
2896 | - 5, |
2897 | - 6 |
2898 | -] |
2899 | |
2900 | === removed file 'tests/click-app-dir/.click/info/com.test.no-version.manifest' |
2901 | --- tests/click-app-dir/.click/info/com.test.no-version.manifest 2013-09-24 03:48:52 +0000 |
2902 | +++ tests/click-app-dir/.click/info/com.test.no-version.manifest 1970-01-01 00:00:00 +0000 |
2903 | @@ -1,8 +0,0 @@ |
2904 | -{ |
2905 | - "ver": "1.2.3", |
2906 | - "hooks": { |
2907 | - "application": { |
2908 | - "desktop": "application.desktop" |
2909 | - } |
2910 | - } |
2911 | -} |
2912 | |
2913 | === removed file 'tests/click-app-dir/application.desktop' |
2914 | --- tests/click-app-dir/application.desktop 2016-07-15 21:51:39 +0000 |
2915 | +++ tests/click-app-dir/application.desktop 1970-01-01 00:00:00 +0000 |
2916 | @@ -1,6 +0,0 @@ |
2917 | -[Desktop Entry] |
2918 | -Version=1.0 |
2919 | -Name=Application |
2920 | -Type=Application |
2921 | -Exec=grep |
2922 | -Icon=foo.png |
2923 | |
2924 | === removed file 'tests/click-app-dir/chatter.desktop' |
2925 | --- tests/click-app-dir/chatter.desktop 2016-04-27 13:44:44 +0000 |
2926 | +++ tests/click-app-dir/chatter.desktop 1970-01-01 00:00:00 +0000 |
2927 | @@ -1,9 +0,0 @@ |
2928 | -[Desktop Entry] |
2929 | -Name=Chatter |
2930 | -Comment=Chat on Internet Relay Chat (IRC) networks |
2931 | -Keywords=irc,online,chat,freenode |
2932 | -Exec=chatter |
2933 | -Icon=chatter.png |
2934 | -Terminal=false |
2935 | -Type=Application |
2936 | -X-Ubuntu-Touch=true |
2937 | |
2938 | === removed file 'tests/click-app-dir/noxmir.desktop' |
2939 | --- tests/click-app-dir/noxmir.desktop 2016-07-15 19:18:49 +0000 |
2940 | +++ tests/click-app-dir/noxmir.desktop 1970-01-01 00:00:00 +0000 |
2941 | @@ -1,9 +0,0 @@ |
2942 | -[Desktop Entry] |
2943 | -Name=No XMir Needed |
2944 | -Type=Application |
2945 | -Exec=noxmir |
2946 | -NoDisplay=false |
2947 | -Hidden=false |
2948 | -Terminal=false |
2949 | -X-Ubuntu-XMir-Enable=false |
2950 | -Icon=nomir.png |
2951 | |
2952 | === removed file 'tests/click-app-dir/xmir.desktop' |
2953 | --- tests/click-app-dir/xmir.desktop 2016-07-15 19:18:49 +0000 |
2954 | +++ tests/click-app-dir/xmir.desktop 1970-01-01 00:00:00 +0000 |
2955 | @@ -1,9 +0,0 @@ |
2956 | -[Desktop Entry] |
2957 | -Name=X Application |
2958 | -Type=Application |
2959 | -Exec=xfoo |
2960 | -NoDisplay=false |
2961 | -Hidden=false |
2962 | -Terminal=false |
2963 | -X-Ubuntu-XMir-Enable=true |
2964 | -Icon=xfoo.png |
2965 | |
2966 | === removed directory 'tests/click-db-dir' |
2967 | === removed file 'tests/click-db-dir/test.conf.in' |
2968 | --- tests/click-db-dir/test.conf.in 2014-03-07 12:33:01 +0000 |
2969 | +++ tests/click-db-dir/test.conf.in 1970-01-01 00:00:00 +0000 |
2970 | @@ -1,2 +0,0 @@ |
2971 | -[Click Database] |
2972 | -root = @CMAKE_CURRENT_SOURCE_DIR@/click-root-dir |
2973 | |
2974 | === removed directory 'tests/click-desktop-hook-db' |
2975 | === removed file 'tests/click-desktop-hook-db/test.conf.in' |
2976 | --- tests/click-desktop-hook-db/test.conf.in 2015-04-06 21:28:13 +0000 |
2977 | +++ tests/click-desktop-hook-db/test.conf.in 1970-01-01 00:00:00 +0000 |
2978 | @@ -1,2 +0,0 @@ |
2979 | -[Click Database] |
2980 | -root = @CMAKE_CURRENT_BINARY_DIR@/click-root-desktop-hook |
2981 | |
2982 | === removed directory 'tests/click-root-dir' |
2983 | === removed directory 'tests/click-root-dir/.click' |
2984 | === removed directory 'tests/click-root-dir/.click/users' |
2985 | === removed directory 'tests/click-root-dir/.click/users/test-user' |
2986 | === removed directory 'tests/click-root-dir/.click/users/test-user-4' |
2987 | === removed symlink 'tests/click-root-dir/.click/users/test-user-4/com.test.good' |
2988 | === target was u'../../../com.test.good/1.2.4/' |
2989 | === removed directory 'tests/click-root-dir/.click/users/test-user-5' |
2990 | === removed symlink 'tests/click-root-dir/.click/users/test-user-5/com.test.good' |
2991 | === target was u'../../../com.test.good/1.2.5/' |
2992 | === removed symlink 'tests/click-root-dir/.click/users/test-user/chatter.robert-ancell' |
2993 | === target was u'../../../chatter.robert-ancell/2/' |
2994 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.bad-version' |
2995 | === target was u'../../../com.test.bad-version/1.2.3' |
2996 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.good' |
2997 | === target was u'../../../com.test.good/1.2.3' |
2998 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.mir' |
2999 | === target was u'../../../com.test.mir/1/' |
3000 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.multiple' |
3001 | === target was u'../../../com.test.multiple/1.2.3' |
3002 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.no-app' |
3003 | === target was u'../../../com.test.no-app/1.2.3' |
3004 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.no-hooks' |
3005 | === target was u'../../../com.test.no-hooks/1.2.3' |
3006 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.no-json' |
3007 | === target was u'../../../com.test.no-json/1.2.3' |
3008 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.no-object' |
3009 | === target was u'../../../com.test.no-object/1.2.3' |
3010 | === removed symlink 'tests/click-root-dir/.click/users/test-user/com.test.no-version' |
3011 | === target was u'../../../com.test.no-version/1.2.3' |
3012 | === removed directory 'tests/click-root-dir/chatter.robert-ancell' |
3013 | === removed symlink 'tests/click-root-dir/chatter.robert-ancell/2' |
3014 | === target was u'../../click-app-dir/' |
3015 | === removed directory 'tests/click-root-dir/com.test.bad-version' |
3016 | === removed symlink 'tests/click-root-dir/com.test.bad-version/1.2.3' |
3017 | === target was u'../../click-app-dir' |
3018 | === removed directory 'tests/click-root-dir/com.test.good' |
3019 | === removed symlink 'tests/click-root-dir/com.test.good/1.2.3' |
3020 | === target was u'../../click-app-dir' |
3021 | === removed directory 'tests/click-root-dir/com.test.good/1.2.4' |
3022 | === removed directory 'tests/click-root-dir/com.test.good/1.2.4/.click' |
3023 | === removed directory 'tests/click-root-dir/com.test.good/1.2.4/.click/info' |
3024 | === removed file 'tests/click-root-dir/com.test.good/1.2.4/.click/info/com.test.good.manifest' |
3025 | --- tests/click-root-dir/com.test.good/1.2.4/.click/info/com.test.good.manifest 2015-06-03 20:26:39 +0000 |
3026 | +++ tests/click-root-dir/com.test.good/1.2.4/.click/info/com.test.good.manifest 1970-01-01 00:00:00 +0000 |
3027 | @@ -1,8 +0,0 @@ |
3028 | -{ |
3029 | - "version": "1.2.4", |
3030 | - "hooks": { |
3031 | - "application": { |
3032 | - "desktop": "application.desktop" |
3033 | - } |
3034 | - } |
3035 | -} |
3036 | |
3037 | === removed symlink 'tests/click-root-dir/com.test.good/1.2.4/application.desktop' |
3038 | === target was u'../../../click-app-dir/application.desktop' |
3039 | === removed directory 'tests/click-root-dir/com.test.good/1.2.5' |
3040 | === removed directory 'tests/click-root-dir/com.test.good/1.2.5/.click' |
3041 | === removed directory 'tests/click-root-dir/com.test.good/1.2.5/.click/info' |
3042 | === removed file 'tests/click-root-dir/com.test.good/1.2.5/.click/info/com.test.good.manifest' |
3043 | --- tests/click-root-dir/com.test.good/1.2.5/.click/info/com.test.good.manifest 2015-06-03 20:26:39 +0000 |
3044 | +++ tests/click-root-dir/com.test.good/1.2.5/.click/info/com.test.good.manifest 1970-01-01 00:00:00 +0000 |
3045 | @@ -1,8 +0,0 @@ |
3046 | -{ |
3047 | - "version": "1.2.5", |
3048 | - "hooks": { |
3049 | - "application": { |
3050 | - "desktop": "application.desktop" |
3051 | - } |
3052 | - } |
3053 | -} |
3054 | |
3055 | === removed symlink 'tests/click-root-dir/com.test.good/1.2.5/application.desktop' |
3056 | === target was u'../../../click-app-dir/application.desktop' |
3057 | === removed directory 'tests/click-root-dir/com.test.mir' |
3058 | === removed symlink 'tests/click-root-dir/com.test.mir/1' |
3059 | === target was u'../../click-app-dir/' |
3060 | === removed directory 'tests/click-root-dir/com.test.multiple' |
3061 | === removed symlink 'tests/click-root-dir/com.test.multiple/1.2.3' |
3062 | === target was u'../../click-app-dir' |
3063 | === removed directory 'tests/click-root-dir/com.test.no-app' |
3064 | === removed symlink 'tests/click-root-dir/com.test.no-app/1.2.3' |
3065 | === target was u'../../click-app-dir' |
3066 | === removed directory 'tests/click-root-dir/com.test.no-hooks' |
3067 | === removed symlink 'tests/click-root-dir/com.test.no-hooks/1.2.3' |
3068 | === target was u'../../click-app-dir' |
3069 | === removed directory 'tests/click-root-dir/com.test.no-json' |
3070 | === removed symlink 'tests/click-root-dir/com.test.no-json/1.2.3' |
3071 | === target was u'../../click-app-dir' |
3072 | === removed directory 'tests/click-root-dir/com.test.no-object' |
3073 | === removed symlink 'tests/click-root-dir/com.test.no-object/1.2.3' |
3074 | === target was u'../../click-app-dir' |
3075 | === removed directory 'tests/click-root-dir/com.test.no-version' |
3076 | === removed symlink 'tests/click-root-dir/com.test.no-version/1.2.3' |
3077 | === target was u'../../click-app-dir' |
3078 | === removed file 'tests/desktop-hook-test.sh.in' |
3079 | --- tests/desktop-hook-test.sh.in 2015-06-03 20:36:34 +0000 |
3080 | +++ tests/desktop-hook-test.sh.in 1970-01-01 00:00:00 +0000 |
3081 | @@ -1,129 +0,0 @@ |
3082 | -#!/bin/bash -e |
3083 | - |
3084 | -TEST_DIR=@CMAKE_CURRENT_BINARY_DIR@ |
3085 | -SRC_DIR=@CMAKE_CURRENT_SOURCE_DIR@ |
3086 | - |
3087 | -CACHE_DIR=${TEST_DIR}/desktop-hook-test-click-dir |
3088 | -CLICK_DIR=${CACHE_DIR}/ubuntu-app-launch/desktop/ |
3089 | - |
3090 | -DATA_DIR=${TEST_DIR}/desktop-hook-test-apps-dir |
3091 | -APPS_DIR=${DATA_DIR}/applications/ |
3092 | - |
3093 | -# Remove the old directories |
3094 | -rm -rf ${CACHE_DIR} |
3095 | -rm -rf ${DATA_DIR} |
3096 | -rm -f @CMAKE_CURRENT_BINARY_DIR@/click-root-desktop-hook |
3097 | - |
3098 | -# Copy our source applications |
3099 | -mkdir -p ${CLICK_DIR} |
3100 | -cp ${SRC_DIR}/link-farm/* ${CLICK_DIR} |
3101 | - |
3102 | -# Build our root dir |
3103 | -ln -s @CMAKE_CURRENT_SOURCE_DIR@/click-root-dir @CMAKE_CURRENT_BINARY_DIR@/click-root-desktop-hook |
3104 | - |
3105 | -# Setup the environment |
3106 | -export XDG_CACHE_HOME=${CACHE_DIR} |
3107 | -export XDG_DATA_HOME=${DATA_DIR} |
3108 | -export TEST_CLICK_DB=@CMAKE_CURRENT_BINARY_DIR@/click-desktop-hook-db |
3109 | -export TEST_CLICK_USER=test-user |
3110 | - |
3111 | -# Run the tool |
3112 | -@CMAKE_BINARY_DIR@/desktop-hook |
3113 | - |
3114 | -# Check that the files exist |
3115 | - |
3116 | -if [ ! -e ${APPS_DIR}/com.test.good_application_1.2.3.desktop ] ; then |
3117 | - echo "Desktop file not created for: com.test.good_application_1.2.3" |
3118 | - exit 1 |
3119 | -fi |
3120 | - |
3121 | -if [ ! -e ${APPS_DIR}/com.test.multiple_first_1.2.3.desktop ] ; then |
3122 | - echo "Desktop file not created for: com.test.multiple_first_1.2.3" |
3123 | - exit 1 |
3124 | -fi |
3125 | - |
3126 | -# Verify we're adding containment to them |
3127 | - |
3128 | -grep "^Exec=aa-exec-click -p com.test.good_application_1.2.3 --" ${APPS_DIR}/com.test.good_application_1.2.3.desktop > /dev/null |
3129 | -grep "^Exec=aa-exec-click -p com.test.multiple_first_1.2.3 --" ${APPS_DIR}/com.test.multiple_first_1.2.3.desktop > /dev/null |
3130 | - |
3131 | -# Make sure they have the AppID (people started using it) :-/ |
3132 | - |
3133 | -grep "^X-Ubuntu-Application-ID=com.test.good_application_1.2.3" ${APPS_DIR}/com.test.good_application_1.2.3.desktop > /dev/null |
3134 | -grep "^X-Ubuntu-Application-ID=com.test.multiple_first_1.2.3" ${APPS_DIR}/com.test.multiple_first_1.2.3.desktop > /dev/null |
3135 | - |
3136 | -# Remove a file and ensure it gets recreated |
3137 | - |
3138 | -rm -f ${APPS_DIR}/com.test.good_application_1.2.3.desktop |
3139 | -@CMAKE_BINARY_DIR@/desktop-hook |
3140 | - |
3141 | -if [ ! -e ${APPS_DIR}/com.test.good_application_1.2.3.desktop ] ; then |
3142 | - echo "Desktop file not recreated for: com.test.good_application_1.2.3" |
3143 | - exit 1 |
3144 | -fi |
3145 | - |
3146 | -# Remove a source file and make sure it goes |
3147 | - |
3148 | -rm -f ${CLICK_DIR}/com.test.multiple_first_1.2.3.desktop |
3149 | -@CMAKE_BINARY_DIR@/desktop-hook |
3150 | -if [ -e ${APPS_DIR}/com.test.multiple_first_1.2.3.desktop ] ; then |
3151 | - echo "Not cleaning up deleted files" |
3152 | - exit 1 |
3153 | -fi |
3154 | - |
3155 | -# Verify the good file is in the desktop hook root |
3156 | -grep "^X-Ubuntu-UAL-Source-Desktop=@CMAKE_CURRENT_BINARY_DIR@/click-root-desktop-hook" ${APPS_DIR}/com.test.good_application_1.2.3.desktop > /dev/null |
3157 | - |
3158 | -# Remove our root |
3159 | -rm -f @CMAKE_CURRENT_BINARY_DIR@/click-root-desktop-hook |
3160 | - |
3161 | -# Point to the new db and run |
3162 | -export TEST_CLICK_DB=@CMAKE_CURRENT_BINARY_DIR@/click-db-dir |
3163 | -@CMAKE_BINARY_DIR@/desktop-hook |
3164 | - |
3165 | -# Verify that we have the file and it's in the new root |
3166 | -if [ ! -e ${APPS_DIR}/com.test.good_application_1.2.3.desktop ] ; then |
3167 | - echo "Desktop file not created for: com.test.good_application_1.2.3" |
3168 | - exit 1 |
3169 | -fi |
3170 | - |
3171 | -grep "^X-Ubuntu-UAL-Source-Desktop=@CMAKE_CURRENT_SOURCE_DIR@/click-root-dir" ${APPS_DIR}/com.test.good_application_1.2.3.desktop > /dev/null |
3172 | - |
3173 | -# Upgrade the good application |
3174 | - |
3175 | -mv ${CLICK_DIR}/com.test.good_application_1.2.3.desktop ${CLICK_DIR}/com.test.good_application_1.2.4.desktop |
3176 | -export TEST_CLICK_USER=test-user-4 |
3177 | - |
3178 | -@CMAKE_BINARY_DIR@/desktop-hook |
3179 | - |
3180 | -if [ -e ${APPS_DIR}/com.test.good_application_1.2.3.desktop ] ; then |
3181 | - echo "Desktop file not removed for: com.test.good_application_1.2.3" |
3182 | - exit 1 |
3183 | -fi |
3184 | - |
3185 | -if [ ! -e ${APPS_DIR}/com.test.good_application_1.2.4.desktop ] ; then |
3186 | - echo "Desktop file not created for: com.test.good_application_1.2.4" |
3187 | - exit 1 |
3188 | -fi |
3189 | - |
3190 | -# Upgrade the good application, but don't have a Source line like in an upgrade scenario |
3191 | - |
3192 | -mv ${CLICK_DIR}/com.test.good_application_1.2.4.desktop ${CLICK_DIR}/com.test.good_application_1.2.5.desktop |
3193 | -cat ${APPS_DIR}/com.test.good_application_1.2.4.desktop | grep -v "^X-Ubuntu-UAL-Source-Desktop" > ${APPS_DIR}/com.test.good_application_1.2.4.desktop.tmp |
3194 | -rm ${APPS_DIR}/com.test.good_application_1.2.4.desktop |
3195 | -mv ${APPS_DIR}/com.test.good_application_1.2.4.desktop.tmp ${APPS_DIR}/com.test.good_application_1.2.4.desktop |
3196 | - |
3197 | -export TEST_CLICK_USER=test-user-5 |
3198 | - |
3199 | - |
3200 | -@CMAKE_BINARY_DIR@/desktop-hook |
3201 | - |
3202 | -if [ -e ${APPS_DIR}/com.test.good_application_1.2.4.desktop ] ; then |
3203 | - echo "Desktop file not removed for: com.test.good_application_1.2.4" |
3204 | - exit 1 |
3205 | -fi |
3206 | - |
3207 | -if [ ! -e ${APPS_DIR}/com.test.good_application_1.2.5.desktop ] ; then |
3208 | - echo "Desktop file not created for: com.test.good_application_1.2.5" |
3209 | - exit 1 |
3210 | -fi |
3211 | |
3212 | === modified file 'tests/helper-handshake-test.cc' |
3213 | --- tests/helper-handshake-test.cc 2016-12-14 21:23:09 +0000 |
3214 | +++ tests/helper-handshake-test.cc 2017-03-21 03:26:40 +0000 |
3215 | @@ -22,7 +22,7 @@ |
3216 | #include <gio/gio.h> |
3217 | |
3218 | extern "C" { |
3219 | -#include "../helpers.h" |
3220 | +#include "utils.h" |
3221 | } |
3222 | |
3223 | class HelperHandshakeTest : public ::testing::Test |
3224 | |
3225 | === modified file 'tests/helper-test.cc' |
3226 | --- tests/helper-test.cc 2017-03-21 03:26:39 +0000 |
3227 | +++ tests/helper-test.cc 2017-03-21 03:26:40 +0000 |
3228 | @@ -23,7 +23,7 @@ |
3229 | #include <gio/gio.h> |
3230 | |
3231 | extern "C" { |
3232 | -#include "../helpers.h" |
3233 | +#include "utils.h" |
3234 | } |
3235 | |
3236 | class HelperTest : public ::testing::Test |
3237 | @@ -78,7 +78,7 @@ |
3238 | g_array_free(output, TRUE); |
3239 | |
3240 | /* Little u with a single URL */ |
3241 | - output = desktop_exec_parse("foo %u", "http://ubuntu.com"); |
3242 | + output = desktop_exec_parse("foo %U", "http://ubuntu.com"); |
3243 | ASSERT_EQ(guint(2), output->len); |
3244 | ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo"); |
3245 | ASSERT_STREQ(g_array_index(output, gchar *, 1), "http://ubuntu.com"); |
3246 | @@ -273,7 +273,7 @@ |
3247 | ASSERT_TRUE(g_key_file_load_from_file(keyfile, CMAKE_SOURCE_DIR "/applications/foo.desktop", G_KEY_FILE_NONE, NULL)); |
3248 | exec = desktop_to_exec(keyfile, ""); |
3249 | ASSERT_TRUE(exec != NULL); |
3250 | - ASSERT_STREQ(exec, "foo"); |
3251 | + ASSERT_STREQ(exec, "foo %U"); |
3252 | g_free(exec); |
3253 | g_key_file_free(keyfile); |
3254 | |
3255 | @@ -316,42 +316,3 @@ |
3256 | return; |
3257 | } |
3258 | |
3259 | -TEST_F(HelperTest, ManifestToDesktop) |
3260 | -{ |
3261 | - gchar * desktop = NULL; |
3262 | - |
3263 | - g_setenv("TEST_CLICK_DB", "click-db-dir", TRUE); |
3264 | - g_setenv("TEST_CLICK_USER", "test-user", TRUE); |
3265 | - |
3266 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.good_application_1.2.3"); |
3267 | - ASSERT_STREQ(CMAKE_SOURCE_DIR "/click-app-dir/application.desktop", desktop); |
3268 | - g_free(desktop); |
3269 | - desktop = NULL; |
3270 | - |
3271 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.bad-version_application_1.2.3"); |
3272 | - ASSERT_TRUE(desktop == NULL); |
3273 | - |
3274 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.no-app_application_1.2.3"); |
3275 | - ASSERT_TRUE(desktop == NULL); |
3276 | - |
3277 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.no-hooks_application_1.2.3"); |
3278 | - ASSERT_TRUE(desktop == NULL); |
3279 | - |
3280 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.no-version_application_1.2.3"); |
3281 | - ASSERT_TRUE(desktop == NULL); |
3282 | - |
3283 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.no-exist_application_1.2.3"); |
3284 | - ASSERT_TRUE(desktop == NULL); |
3285 | - |
3286 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.no-json_application_1.2.3"); |
3287 | - ASSERT_TRUE(desktop == NULL); |
3288 | - |
3289 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.no-object_application_1.2.3"); |
3290 | - ASSERT_TRUE(desktop == NULL); |
3291 | - |
3292 | - /* Bad App ID */ |
3293 | - desktop = manifest_to_desktop(CMAKE_SOURCE_DIR "/click-app-dir/", "com.test.good_application-1.2.3"); |
3294 | - ASSERT_TRUE(desktop == NULL); |
3295 | - |
3296 | - return; |
3297 | -} |
3298 | |
3299 | === modified file 'tests/libertine-service.h' |
3300 | --- tests/libertine-service.h 2017-02-15 15:03:41 +0000 |
3301 | +++ tests/libertine-service.h 2017-03-21 03:26:40 +0000 |
3302 | @@ -42,6 +42,7 @@ |
3303 | |
3304 | wait = dbus_test_task_new(); |
3305 | dbus_test_task_set_wait_for(wait, "com.canonical.libertine.Service"); |
3306 | + dbus_test_task_set_name(wait, "lib-wait"); |
3307 | } |
3308 | |
3309 | ~LibertineService() |
3310 | |
3311 | === modified file 'tests/libual-cpp-test.cc' |
3312 | --- tests/libual-cpp-test.cc 2017-03-21 03:26:39 +0000 |
3313 | +++ tests/libual-cpp-test.cc 2017-03-21 03:26:40 +0000 |
3314 | @@ -31,6 +31,7 @@ |
3315 | |
3316 | #include "application.h" |
3317 | #include "glib-thread.h" |
3318 | +#include "helper-impl.h" |
3319 | #include "helper.h" |
3320 | #include "jobs-base.h" |
3321 | #include "registry.h" |
3322 | @@ -39,17 +40,15 @@ |
3323 | #include "eventually-fixture.h" |
3324 | #include "libertine-service.h" |
3325 | #include "mir-mock.h" |
3326 | +#include "registry-mock.h" |
3327 | +#include "snapd-mock.h" |
3328 | #include "spew-master.h" |
3329 | #include "systemd-mock.h" |
3330 | #include "zg-mock.h" |
3331 | |
3332 | -#ifdef ENABLE_SNAPPY |
3333 | -#include "snapd-mock.h" |
3334 | - |
3335 | #define LOCAL_SNAPD_TEST_SOCKET (SNAPD_TEST_SOCKET "-libual-cpp-test") |
3336 | -#endif |
3337 | |
3338 | -#define CGROUP_DIR (CMAKE_BINARY_DIR "/systemd-cgroups") |
3339 | +#define CGROUP_DIR (CMAKE_BINARY_DIR "/systemd-libual-cpp-cgroups") |
3340 | |
3341 | class LibUAL : public EventuallyFixture |
3342 | { |
3343 | @@ -99,6 +98,7 @@ |
3344 | const std::shared_ptr<ubuntu::app_launch::Application::Instance>& instance, |
3345 | std::function<void(bool)> reply) override |
3346 | { |
3347 | + g_debug("Manager Mock: Starting Request: %s", std::string(app->appId()).c_str()); |
3348 | thread.timeout(startingTimeout, [this, app, instance, reply]() { |
3349 | lastStartedApp = app->appId(); |
3350 | reply(startingResponse); |
3351 | @@ -109,6 +109,7 @@ |
3352 | const std::shared_ptr<ubuntu::app_launch::Application::Instance>& instance, |
3353 | std::function<void(bool)> reply) override |
3354 | { |
3355 | + g_debug("Manager Mock: Focus Request: %s", std::string(app->appId()).c_str()); |
3356 | thread.timeout(focusTimeout, [this, app, instance, reply]() { |
3357 | lastFocusedApp = app->appId(); |
3358 | reply(focusResponse); |
3359 | @@ -119,6 +120,7 @@ |
3360 | const std::shared_ptr<ubuntu::app_launch::Application::Instance>& instance, |
3361 | std::function<void(bool)> reply) override |
3362 | { |
3363 | + g_debug("Manager Mock: Resume Request: %s", std::string(app->appId()).c_str()); |
3364 | thread.timeout(resumeTimeout, [this, app, instance, reply]() { |
3365 | lastResumedApp = app->appId(); |
3366 | reply(resumeResponse); |
3367 | @@ -147,24 +149,15 @@ |
3368 | |
3369 | virtual void SetUp() |
3370 | { |
3371 | - /* Click DB test mode */ |
3372 | - g_setenv("TEST_CLICK_DB", CMAKE_BINARY_DIR "/click-db-dir", TRUE); |
3373 | - g_setenv("TEST_CLICK_USER", "test-user", TRUE); |
3374 | - |
3375 | - gchar* linkfarmpath = g_build_filename(CMAKE_SOURCE_DIR, "link-farm", NULL); |
3376 | - g_setenv("UBUNTU_APP_LAUNCH_LINK_FARM", linkfarmpath, TRUE); |
3377 | - g_free(linkfarmpath); |
3378 | - |
3379 | g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE); |
3380 | g_setenv("XDG_CACHE_HOME", CMAKE_SOURCE_DIR "/libertine-data", TRUE); |
3381 | g_setenv("XDG_DATA_HOME", CMAKE_SOURCE_DIR "/libertine-home", TRUE); |
3382 | |
3383 | -#ifdef ENABLE_SNAPPY |
3384 | g_setenv("UBUNTU_APP_LAUNCH_SNAPD_SOCKET", LOCAL_SNAPD_TEST_SOCKET, TRUE); |
3385 | g_setenv("UBUNTU_APP_LAUNCH_SNAP_BASEDIR", SNAP_BASEDIR, TRUE); |
3386 | g_setenv("UBUNTU_APP_LAUNCH_DISABLE_SNAPD_TIMEOUT", "You betcha!", TRUE); |
3387 | g_unlink(LOCAL_SNAPD_TEST_SOCKET); |
3388 | -#endif |
3389 | + |
3390 | g_setenv("UBUNTU_APP_LAUNCH_SYSTEMD_PATH", "/this/should/not/exist", TRUE); |
3391 | /* Setting the cgroup temp directory */ |
3392 | g_setenv("UBUNTU_APP_LAUNCH_SYSTEMD_CGROUP_ROOT", CGROUP_DIR, TRUE); |
3393 | @@ -175,12 +168,11 @@ |
3394 | |
3395 | systemd = std::make_shared<SystemdMock>( |
3396 | std::list<SystemdMock::Instance>{ |
3397 | - {"application-click", "com.test.good_application_1.2.3", {}, getpid(), {100, 200, 300}}, |
3398 | {"application-snap", "unity8-package_foo_x123", {}, getpid(), {100, 200, 300}}, |
3399 | {"application-legacy", "multiple", "2342345", 5678, {100, 200, 300}}, |
3400 | - {"application-legacy", "single", {}, 5678, {100, 200, 300}}, |
3401 | - {"helper", "com.foo_bar_43.23.12", {}, 1, {100, 200, 300}}, |
3402 | - {"helper", "com.bar_foo_8432.13.1", "24034582324132", 1, {100, 200, 300}}}, |
3403 | + {"application-legacy", "single", {}, getpid(), {getpid()}}, |
3404 | + {"untrusted-helper", "com.foo_bar_43.23.12", {}, 1, {100, 200, 300}}, |
3405 | + {"untrusted-helper", "com.bar_foo_8432.13.1", "24034582324132", 1, {100, 200, 300}}}, |
3406 | CGROUP_DIR); |
3407 | |
3408 | /* Put it together */ |
3409 | @@ -197,9 +189,6 @@ |
3410 | g_dbus_connection_set_exit_on_close(bus, FALSE); |
3411 | g_object_add_weak_pointer(G_OBJECT(bus), (gpointer*)&bus); |
3412 | |
3413 | - /* Make sure we pretend the CG manager is just on our bus */ |
3414 | - g_setenv("UBUNTU_APP_LAUNCH_CG_MANAGER_SESSION_BUS", "YES", TRUE); |
3415 | - |
3416 | registry = std::make_shared<ubuntu::app_launch::Registry>(); |
3417 | |
3418 | manager = std::make_shared<ManagerMock>(); |
3419 | @@ -226,9 +215,7 @@ |
3420 | |
3421 | ASSERT_EVENTUALLY_EQ(nullptr, bus); |
3422 | |
3423 | -#ifdef ENABLE_SNAPPY |
3424 | g_unlink(LOCAL_SNAPD_TEST_SOCKET); |
3425 | -#endif |
3426 | } |
3427 | |
3428 | static std::string find_env(std::set<std::string>& envs, std::string var) |
3429 | @@ -266,6 +253,55 @@ |
3430 | } |
3431 | return split_env(val).second == value; |
3432 | } |
3433 | + |
3434 | + void storeForApp(const ubuntu::app_launch::AppID& appid, const std::string& jobtype, const std::string& instanceid) |
3435 | + { |
3436 | + auto store = storeForHelper(appid); |
3437 | + |
3438 | + ON_CALL(*store, list(testing::_)) |
3439 | + .WillByDefault(testing::Return(std::list<std::shared_ptr<ubuntu::app_launch::Application>>{})); |
3440 | + |
3441 | + auto app = std::make_shared<MockApp>(appid, registry); |
3442 | + ON_CALL(*store, create(appid, testing::_)).WillByDefault(testing::Return(app)); |
3443 | + |
3444 | + if (!instanceid.empty()) |
3445 | + { |
3446 | + std::vector<ubuntu::app_launch::Application::URL> urls; |
3447 | + auto inst = std::make_shared<MockInst>(appid, jobtype, instanceid, urls, registry); |
3448 | + ON_CALL(*app, findInstance(instanceid)).WillByDefault(testing::Return(inst)); |
3449 | + ON_CALL(*app, launch(testing::_)).WillByDefault(testing::Return(inst)); |
3450 | + ON_CALL(*app, launchTest(testing::_)).WillByDefault(testing::Return(inst)); |
3451 | + ON_CALL(*app, hasInstances()).WillByDefault(testing::Return(true)); |
3452 | + } |
3453 | + else |
3454 | + { |
3455 | + ON_CALL(*app, hasInstances()).WillByDefault(testing::Return(false)); |
3456 | + } |
3457 | + |
3458 | + std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> list; |
3459 | + list.push_back(store); |
3460 | + registry->impl->setAppStores(list); |
3461 | + } |
3462 | + |
3463 | + std::shared_ptr<MockStore> storeForHelper(const ubuntu::app_launch::AppID& appid) |
3464 | + { |
3465 | + /* Setup a store for looking up the AppID */ |
3466 | + auto store = std::make_shared<MockStore>(); |
3467 | + |
3468 | + ON_CALL(*store, verifyPackage(appid.package, testing::_)).WillByDefault(testing::Return(true)); |
3469 | + ON_CALL(*store, verifyAppname(appid.package, appid.appname, testing::_)).WillByDefault(testing::Return(true)); |
3470 | + ON_CALL(*store, findAppname(appid.package, testing::_, testing::_)) |
3471 | + .WillByDefault(testing::Return(appid.appname)); |
3472 | + ON_CALL(*store, findVersion(appid.package, appid.appname, testing::_)) |
3473 | + .WillByDefault(testing::Return(appid.version)); |
3474 | + ON_CALL(*store, hasAppId(appid, testing::_)).WillByDefault(testing::Return(true)); |
3475 | + |
3476 | + std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>> list; |
3477 | + list.push_back(store); |
3478 | + registry->impl->setAppStores(list); |
3479 | + |
3480 | + return store; |
3481 | + } |
3482 | }; |
3483 | |
3484 | #define TASK_STATE(task) \ |
3485 | @@ -274,7 +310,6 @@ |
3486 | [&task] { return dbus_test_task_get_state(DBUS_TEST_TASK(task)); } \ |
3487 | } |
3488 | |
3489 | -#ifdef ENABLE_SNAPPY |
3490 | /* Snapd mock data */ |
3491 | static std::pair<std::string, std::string> interfaces{ |
3492 | "GET /v2/interfaces HTTP/1.1\r\nHost: snapd\r\nAccept: */*\r\n\r\n", |
3493 | @@ -286,8 +321,8 @@ |
3494 | "unity8-package", "active", "app", "1.2.3.4", "x123", {"foo", "single", "xmir", "noxmir"})))}; |
3495 | static std::pair<std::string, std::string> helloPackage{ |
3496 | "GET /v2/snaps/hello HTTP/1.1\r\nHost: snapd\r\nAccept: */*\r\n\r\n", |
3497 | - SnapdMock::httpJsonResponse(SnapdMock::snapdOkay(SnapdMock::packageJson( |
3498 | - "hello", "active", "app", "1.0", "1", {"hello"})))}; |
3499 | + SnapdMock::httpJsonResponse( |
3500 | + SnapdMock::snapdOkay(SnapdMock::packageJson("hello", "active", "app", "1.0", "1", {"hello"})))}; |
3501 | |
3502 | TEST_F(LibUAL, ApplicationIdSnap) |
3503 | { |
3504 | @@ -356,23 +391,20 @@ |
3505 | |
3506 | auto appid = ubuntu::app_launch::AppID::parse("hello_hello_1"); |
3507 | |
3508 | - try { |
3509 | - ubuntu::app_launch::Application::create(appid, registry); |
3510 | - FAIL() << "Expected std::runtime_error"; |
3511 | - } |
3512 | - catch(std::runtime_error const & err) { |
3513 | - EXPECT_EQ(err.what(), std::string("Graphical interface not found for: hello_hello_1")); |
3514 | - } |
3515 | - catch(...) { |
3516 | - FAIL() << "Expected std::runtime_error"; |
3517 | - } |
3518 | + EXPECT_THROW(ubuntu::app_launch::Application::create(appid, registry), std::runtime_error); |
3519 | } |
3520 | -#endif |
3521 | |
3522 | TEST_F(LibUAL, ApplicationPid) |
3523 | { |
3524 | + /* Queries come in threes, apparently */ |
3525 | + SnapdMock snapd{LOCAL_SNAPD_TEST_SOCKET, |
3526 | + { |
3527 | + u8Package, interfaces, u8Package, /* App */ |
3528 | + }}; |
3529 | + registry = std::make_shared<ubuntu::app_launch::Registry>(); |
3530 | + |
3531 | /* Check bad params */ |
3532 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3533 | + auto appid = ubuntu::app_launch::AppID::parse("unity8-package_foo_x123"); |
3534 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
3535 | |
3536 | ASSERT_LT(0, int(app->instances().size())); |
3537 | @@ -393,93 +425,143 @@ |
3538 | ASSERT_LT(0, int(instances.size())); |
3539 | EXPECT_EQ(5678, instances[0]->primaryPid()); |
3540 | |
3541 | - /* Look at the full PID list from CG Manager */ |
3542 | - DbusTestDbusMockObject* cgobject = dbus_test_dbus_mock_get_object(cgmock, "/org/linuxcontainers/cgmanager", |
3543 | - "org.linuxcontainers.cgmanager0_0", NULL); |
3544 | - const DbusTestDbusMockCall* calls = NULL; |
3545 | - guint len = 0; |
3546 | - |
3547 | - /* Click in the set */ |
3548 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL)); |
3549 | - EXPECT_TRUE(app->instances()[0]->hasPid(100)); |
3550 | - calls = dbus_test_dbus_mock_object_get_method_calls(cgmock, cgobject, "GetTasksRecursive", &len, NULL); |
3551 | - ASSERT_EQ(1u, len); |
3552 | - EXPECT_STREQ("GetTasksRecursive", calls->name); |
3553 | - EXPECT_TRUE(g_variant_equal( |
3554 | - calls->params, g_variant_new("(ss)", "freezer", "upstart/application-click-com.test.good_application_1.2.3"))); |
3555 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL)); |
3556 | - |
3557 | - /* Click out of the set */ |
3558 | - EXPECT_FALSE(app->instances()[0]->hasPid(101)); |
3559 | - calls = dbus_test_dbus_mock_object_get_method_calls(cgmock, cgobject, "GetTasksRecursive", &len, NULL); |
3560 | - ASSERT_EQ(1u, len); |
3561 | - EXPECT_STREQ("GetTasksRecursive", calls->name); |
3562 | - EXPECT_TRUE(g_variant_equal( |
3563 | - calls->params, g_variant_new("(ss)", "freezer", "upstart/application-click-com.test.good_application_1.2.3"))); |
3564 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL)); |
3565 | - |
3566 | /* Legacy Single Instance */ |
3567 | auto singleappid = ubuntu::app_launch::AppID::find(registry, "single"); |
3568 | auto singleapp = ubuntu::app_launch::Application::create(singleappid, registry); |
3569 | |
3570 | ASSERT_LT(0, int(singleapp->instances().size())); |
3571 | - EXPECT_TRUE(singleapp->instances()[0]->hasPid(100)); |
3572 | - |
3573 | - calls = dbus_test_dbus_mock_object_get_method_calls(cgmock, cgobject, "GetTasksRecursive", &len, NULL); |
3574 | - ASSERT_EQ(1u, len); |
3575 | - EXPECT_STREQ("GetTasksRecursive", calls->name); |
3576 | - EXPECT_TRUE(g_variant_equal(calls->params, g_variant_new("(ss)", "freezer", "upstart/application-legacy-single-"))); |
3577 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL)); |
3578 | - |
3579 | - /* Legacy Multi Instance */ |
3580 | - EXPECT_TRUE(multiapp->instances()[0]->hasPid(100)); |
3581 | - calls = dbus_test_dbus_mock_object_get_method_calls(cgmock, cgobject, "GetTasksRecursive", &len, NULL); |
3582 | - ASSERT_EQ(1u, len); |
3583 | - EXPECT_STREQ("GetTasksRecursive", calls->name); |
3584 | - EXPECT_TRUE(g_variant_equal(calls->params, |
3585 | - g_variant_new("(ss)", "freezer", "upstart/application-legacy-multiple-2342345"))); |
3586 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(cgmock, cgobject, NULL)); |
3587 | + EXPECT_TRUE(singleapp->instances()[0]->hasPid(getpid())); |
3588 | } |
3589 | |
3590 | TEST_F(LibUAL, ApplicationId) |
3591 | { |
3592 | - g_setenv("TEST_CLICK_DB", "click-db-dir", TRUE); |
3593 | - g_setenv("TEST_CLICK_USER", "test-user", TRUE); |
3594 | + auto mockstore = std::make_shared<MockStore>(); |
3595 | + registry = |
3596 | + std::make_shared<RegistryMock>(std::list<std::shared_ptr<ubuntu::app_launch::app_store::Base>>{mockstore}); |
3597 | + |
3598 | + EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_)) |
3599 | + .WillOnce(testing::Return(true)); |
3600 | + EXPECT_CALL(*mockstore, verifyAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3601 | + ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_)) |
3602 | + .WillOnce(testing::Return(true)); |
3603 | + EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3604 | + ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_)) |
3605 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3"))); |
3606 | |
3607 | /* Test with current-user-version, should return the version in the manifest */ |
3608 | EXPECT_EQ("com.test.good_application_1.2.3", |
3609 | (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application")); |
3610 | |
3611 | + EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_)) |
3612 | + .WillOnce(testing::Return(true)); |
3613 | + EXPECT_CALL(*mockstore, verifyAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3614 | + ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_)) |
3615 | + .WillOnce(testing::Return(true)); |
3616 | + EXPECT_CALL(*mockstore, |
3617 | + hasAppId(ubuntu::app_launch::AppID{ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3618 | + ubuntu::app_launch::AppID::AppName::from_raw("application"), |
3619 | + ubuntu::app_launch::AppID::Version::from_raw("1.2.4")}, |
3620 | + testing::_)) |
3621 | + .WillOnce(testing::Return(true)); |
3622 | + |
3623 | /* Test with version specified, shouldn't even read the manifest */ |
3624 | EXPECT_EQ("com.test.good_application_1.2.4", |
3625 | (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "application", "1.2.4")); |
3626 | |
3627 | + EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_)) |
3628 | + .WillOnce(testing::Return(true)); |
3629 | + EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3630 | + ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED, testing::_)) |
3631 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("application"))); |
3632 | + EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3633 | + ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_)) |
3634 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3"))); |
3635 | + |
3636 | /* Test with out a version or app, should return the version in the manifest */ |
3637 | EXPECT_EQ("com.test.good_application_1.2.3", |
3638 | (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.good", "first-listed-app", |
3639 | "current-user-version")); |
3640 | |
3641 | /* Make sure we can select the app from a list correctly */ |
3642 | + EXPECT_CALL(*mockstore, |
3643 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_)) |
3644 | + .WillOnce(testing::Return(true)); |
3645 | + EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3646 | + ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED, testing::_)) |
3647 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("first"))); |
3648 | + EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3649 | + ubuntu::app_launch::AppID::AppName::from_raw("first"), testing::_)) |
3650 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3"))); |
3651 | EXPECT_EQ("com.test.multiple_first_1.2.3", |
3652 | (std::string)ubuntu::app_launch::AppID::discover( |
3653 | registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED)); |
3654 | + |
3655 | + EXPECT_CALL(*mockstore, |
3656 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_)) |
3657 | + .WillOnce(testing::Return(true)); |
3658 | + EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3659 | + ubuntu::app_launch::AppID::ApplicationWildcard::FIRST_LISTED, testing::_)) |
3660 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("first"))); |
3661 | + EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3662 | + ubuntu::app_launch::AppID::AppName::from_raw("first"), testing::_)) |
3663 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3"))); |
3664 | EXPECT_EQ("com.test.multiple_first_1.2.3", |
3665 | (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.multiple")); |
3666 | + |
3667 | + EXPECT_CALL(*mockstore, |
3668 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_)) |
3669 | + .WillOnce(testing::Return(true)); |
3670 | + EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3671 | + ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED, testing::_)) |
3672 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("fifth"))); |
3673 | + EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3674 | + ubuntu::app_launch::AppID::AppName::from_raw("fifth"), testing::_)) |
3675 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3"))); |
3676 | EXPECT_EQ("com.test.multiple_fifth_1.2.3", |
3677 | (std::string)ubuntu::app_launch::AppID::discover( |
3678 | registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::LAST_LISTED)); |
3679 | + |
3680 | + EXPECT_CALL(*mockstore, |
3681 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), testing::_)) |
3682 | + .WillOnce(testing::Return(true)); |
3683 | + EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.multiple"), |
3684 | + ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED, testing::_)) |
3685 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw(""))); |
3686 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover( |
3687 | registry, "com.test.multiple", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED)); |
3688 | + |
3689 | + EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), testing::_)) |
3690 | + .WillOnce(testing::Return(true)); |
3691 | + EXPECT_CALL(*mockstore, findAppname(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3692 | + ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED, testing::_)) |
3693 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::AppName::from_raw("application"))); |
3694 | + EXPECT_CALL(*mockstore, findVersion(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3695 | + ubuntu::app_launch::AppID::AppName::from_raw("application"), testing::_)) |
3696 | + .WillOnce(testing::Return(ubuntu::app_launch::AppID::Version::from_raw("1.2.3"))); |
3697 | EXPECT_EQ("com.test.good_application_1.2.3", |
3698 | (std::string)ubuntu::app_launch::AppID::discover( |
3699 | registry, "com.test.good", ubuntu::app_launch::AppID::ApplicationWildcard::ONLY_LISTED)); |
3700 | |
3701 | /* A bunch that should be NULL */ |
3702 | + EXPECT_CALL(*mockstore, |
3703 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-hooks"), testing::_)) |
3704 | + .WillOnce(testing::Return(false)); |
3705 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-hooks")); |
3706 | + EXPECT_CALL(*mockstore, verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-json"), testing::_)) |
3707 | + .WillOnce(testing::Return(false)); |
3708 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-json")); |
3709 | + EXPECT_CALL(*mockstore, |
3710 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-object"), testing::_)) |
3711 | + .WillOnce(testing::Return(false)); |
3712 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-object")); |
3713 | + EXPECT_CALL(*mockstore, |
3714 | + verifyPackage(ubuntu::app_launch::AppID::Package::from_raw("com.test.no-version"), testing::_)) |
3715 | + .WillOnce(testing::Return(false)); |
3716 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "com.test.no-version")); |
3717 | +} |
3718 | |
3719 | +TEST_F(LibUAL, ApplicationIdLibertine) |
3720 | +{ |
3721 | /* Libertine tests */ |
3722 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name")); |
3723 | EXPECT_EQ("", (std::string)ubuntu::app_launch::AppID::discover(registry, "container-name", "not-exist")); |
3724 | @@ -492,9 +574,7 @@ |
3725 | TEST_F(LibUAL, AppIdParse) |
3726 | { |
3727 | EXPECT_FALSE(ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123").empty()); |
3728 | - EXPECT_FALSE(ubuntu::app_launch::AppID::find(registry, "inkscape").empty()); |
3729 | EXPECT_FALSE(ubuntu::app_launch::AppID::parse("chatter.robert-ancell_chatter_2").empty()); |
3730 | - EXPECT_FALSE(ubuntu::app_launch::AppID::find(registry, "chatter.robert-ancell_chatter").empty()); |
3731 | |
3732 | auto id = ubuntu::app_launch::AppID::parse("com.ubuntu.test_test_123"); |
3733 | |
3734 | @@ -508,18 +588,12 @@ |
3735 | |
3736 | TEST_F(LibUAL, ApplicationList) |
3737 | { |
3738 | -#ifdef ENABLE_SNAPPY |
3739 | SnapdMock snapd{LOCAL_SNAPD_TEST_SOCKET, {u8Package, interfaces, u8Package}}; |
3740 | registry = std::make_shared<ubuntu::app_launch::Registry>(); |
3741 | -#endif |
3742 | |
3743 | auto apps = ubuntu::app_launch::Registry::runningApps(registry); |
3744 | |
3745 | -#ifdef ENABLE_SNAPPY |
3746 | - ASSERT_EQ(4, int(apps.size())); |
3747 | -#else |
3748 | - ASSERT_EQ(3, int(apps.size())); |
3749 | -#endif |
3750 | + ASSERT_EQ(3u, apps.size()); |
3751 | |
3752 | apps.sort([](const std::shared_ptr<ubuntu::app_launch::Application>& a, |
3753 | const std::shared_ptr<ubuntu::app_launch::Application>& b) { |
3754 | @@ -529,10 +603,8 @@ |
3755 | return sa < sb; |
3756 | }); |
3757 | |
3758 | - EXPECT_EQ("com.test.good_application_1.2.3", (std::string)apps.front()->appId()); |
3759 | -#ifdef ENABLE_SNAPPY |
3760 | + EXPECT_EQ("multiple", (std::string)apps.front()->appId()); |
3761 | EXPECT_EQ("unity8-package_foo_x123", (std::string)apps.back()->appId()); |
3762 | -#endif |
3763 | } |
3764 | |
3765 | TEST_F(LibUAL, StartingResponses) |
3766 | @@ -559,17 +631,17 @@ |
3767 | |
3768 | /* Emit a signal */ |
3769 | g_dbus_connection_emit_signal( |
3770 | - session, NULL, /* destination */ |
3771 | - "/", /* path */ |
3772 | - "com.canonical.UbuntuAppLaunch", /* interface */ |
3773 | - "UnityStartingBroadcast", /* signal */ |
3774 | - g_variant_new("(ss)", "com.test.good_application_1.2.3", "goodinstance"), /* params, the same */ |
3775 | + session, NULL, /* destination */ |
3776 | + "/", /* path */ |
3777 | + "com.canonical.UbuntuAppLaunch", /* interface */ |
3778 | + "UnityStartingBroadcast", /* signal */ |
3779 | + g_variant_new("(ss)", "container-name_test_0.0", "goodinstance"), /* params, the same */ |
3780 | NULL); |
3781 | |
3782 | /* Make sure we run our observer */ |
3783 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID(ubuntu::app_launch::AppID::Package::from_raw("com.test.good"), |
3784 | - ubuntu::app_launch::AppID::AppName::from_raw("application"), |
3785 | - ubuntu::app_launch::AppID::Version::from_raw("1.2.3")), |
3786 | + EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID(ubuntu::app_launch::AppID::Package::from_raw("container-name"), |
3787 | + ubuntu::app_launch::AppID::AppName::from_raw("test"), |
3788 | + ubuntu::app_launch::AppID::Version::from_raw("0.0")), |
3789 | manager->lastStartedApp); |
3790 | |
3791 | /* Make sure we return */ |
3792 | @@ -581,119 +653,57 @@ |
3793 | |
3794 | TEST_F(LibUAL, AppIdTest) |
3795 | { |
3796 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3797 | + auto appid = ubuntu::app_launch::AppID::find(registry, "single"); |
3798 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
3799 | app->launch(); |
3800 | |
3801 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3802 | - this->manager->lastFocusedApp); |
3803 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3804 | - this->manager->lastResumedApp); |
3805 | -} |
3806 | - |
3807 | -GDBusMessage* filter_func_good(GDBusConnection* conn, GDBusMessage* message, gboolean incomming, gpointer user_data) |
3808 | -{ |
3809 | - if (!incomming) |
3810 | - { |
3811 | - return message; |
3812 | - } |
3813 | - |
3814 | - if (g_strcmp0(g_dbus_message_get_path(message), (gchar*)user_data) == 0) |
3815 | - { |
3816 | - GDBusMessage* reply = g_dbus_message_new_method_reply(message); |
3817 | - g_dbus_connection_send_message(conn, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); |
3818 | - g_object_unref(message); |
3819 | - return NULL; |
3820 | - } |
3821 | - |
3822 | - return message; |
3823 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastFocusedApp); |
3824 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastResumedApp); |
3825 | } |
3826 | |
3827 | TEST_F(LibUAL, UrlSendTest) |
3828 | { |
3829 | - GDBusConnection* session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); |
3830 | - guint filter = g_dbus_connection_add_filter(session, filter_func_good, |
3831 | - (gpointer) "/com_2etest_2egood_5fapplication_5f1_2e2_2e3", NULL); |
3832 | - |
3833 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3834 | - auto app = ubuntu::app_launch::Application::create(appid, registry); |
3835 | - std::vector<ubuntu::app_launch::Application::URL> uris = { |
3836 | - ubuntu::app_launch::Application::URL::from_raw("http://www.test.com")}; |
3837 | - |
3838 | - app->launch(uris); |
3839 | - |
3840 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3841 | - this->manager->lastFocusedApp); |
3842 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3843 | - this->manager->lastResumedApp); |
3844 | - |
3845 | - g_dbus_connection_remove_filter(session, filter); |
3846 | - |
3847 | - /* Send multiple resume responses to ensure we unsubscribe */ |
3848 | - /* Multiple to increase our chance of hitting a bad free in the middle, |
3849 | - fun with async! */ |
3850 | - int i; |
3851 | - for (i = 0; i < 5; i++) |
3852 | - { |
3853 | - g_dbus_connection_emit_signal( |
3854 | - session, NULL, /* destination */ |
3855 | - "/", /* path */ |
3856 | - "com.canonical.UbuntuAppLaunch", /* interface */ |
3857 | - "UnityResumeResponse", /* signal */ |
3858 | - g_variant_new("(ss)", "com.test.good_application_1.2.3", "goodinstance"), /* params, the same */ |
3859 | - NULL); |
3860 | - |
3861 | - pause(50); /* Ensure all the events come through */ |
3862 | - } |
3863 | - |
3864 | - g_object_unref(session); |
3865 | -} |
3866 | - |
3867 | -TEST_F(LibUAL, UrlSendNoObjectTest) |
3868 | -{ |
3869 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3870 | - auto app = ubuntu::app_launch::Application::create(appid, registry); |
3871 | - std::vector<ubuntu::app_launch::Application::URL> uris = { |
3872 | - ubuntu::app_launch::Application::URL::from_raw("http://www.test.com")}; |
3873 | - |
3874 | - app->launch(uris); |
3875 | - |
3876 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3877 | - this->manager->lastFocusedApp); |
3878 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3879 | - this->manager->lastResumedApp); |
3880 | + auto appid = ubuntu::app_launch::AppID::find(registry, "foo"); |
3881 | + auto app = ubuntu::app_launch::Application::create(appid, registry); |
3882 | + std::vector<ubuntu::app_launch::Application::URL> uris = { |
3883 | + ubuntu::app_launch::Application::URL::from_raw("http://www.test.com")}; |
3884 | + |
3885 | + app->launch(uris); |
3886 | + |
3887 | + std::list<SystemdMock::TransientUnit> calls; |
3888 | + ASSERT_EVENTUALLY_FUNC_LT(0u, std::function<unsigned int(void)>([&]() { |
3889 | + calls = systemd->unitCalls(); |
3890 | + return calls.size(); |
3891 | + })); |
3892 | + EXPECT_EQ("http://www.test.com", *calls.begin()->execline.rbegin()); |
3893 | } |
3894 | |
3895 | TEST_F(LibUAL, UnityTimeoutTest) |
3896 | { |
3897 | this->resume_timeout = 100; |
3898 | |
3899 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3900 | + auto appid = ubuntu::app_launch::AppID::find(registry, "single"); |
3901 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
3902 | |
3903 | app->launch(); |
3904 | |
3905 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3906 | - this->manager->lastResumedApp); |
3907 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3908 | - this->manager->lastFocusedApp); |
3909 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastResumedApp); |
3910 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastFocusedApp); |
3911 | } |
3912 | |
3913 | TEST_F(LibUAL, UnityTimeoutUriTest) |
3914 | { |
3915 | this->resume_timeout = 200; |
3916 | |
3917 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3918 | + auto appid = ubuntu::app_launch::AppID::find(registry, "single"); |
3919 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
3920 | std::vector<ubuntu::app_launch::Application::URL> uris = { |
3921 | ubuntu::app_launch::Application::URL::from_raw("http://www.test.com")}; |
3922 | |
3923 | app->launch(uris); |
3924 | |
3925 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3926 | - this->manager->lastFocusedApp); |
3927 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3928 | - this->manager->lastResumedApp); |
3929 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastFocusedApp); |
3930 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastResumedApp); |
3931 | } |
3932 | |
3933 | GDBusMessage* filter_respawn(GDBusConnection* conn, GDBusMessage* message, gboolean incomming, gpointer user_data) |
3934 | @@ -714,7 +724,7 @@ |
3935 | |
3936 | guint start = g_get_monotonic_time(); |
3937 | |
3938 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"); |
3939 | + auto appid = ubuntu::app_launch::AppID::find(registry, "single"); |
3940 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
3941 | std::vector<ubuntu::app_launch::Application::URL> uris = { |
3942 | ubuntu::app_launch::Application::URL::from_raw("http://www.test.com")}; |
3943 | @@ -726,10 +736,8 @@ |
3944 | g_debug("Start call time: %d ms", (end - start) / 1000); |
3945 | EXPECT_LT(end - start, guint(2000 * 1000)); |
3946 | |
3947 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3948 | - this->manager->lastFocusedApp); |
3949 | - EXPECT_EVENTUALLY_EQ(ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.3"), |
3950 | - this->manager->lastResumedApp); |
3951 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastFocusedApp); |
3952 | + EXPECT_EVENTUALLY_EQ(appid, this->manager->lastResumedApp); |
3953 | |
3954 | g_dbus_connection_remove_filter(session, filter); |
3955 | g_object_unref(session); |
3956 | @@ -768,10 +776,12 @@ |
3957 | |
3958 | TEST_F(LibUAL, StartHelper) |
3959 | { |
3960 | + auto appid = ubuntu::app_launch::AppID::parse("com.test.multiple_first_1.2.3"); |
3961 | auto untrusted = ubuntu::app_launch::Helper::Type::from_raw("untrusted-type"); |
3962 | |
3963 | + storeForHelper(appid); |
3964 | + |
3965 | /* Basic make sure we can send the event */ |
3966 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.multiple_first_1.2.3"); |
3967 | auto helper = ubuntu::app_launch::Helper::create(untrusted, appid, registry); |
3968 | |
3969 | auto inst = helper->launch(); |
3970 | @@ -782,7 +792,7 @@ |
3971 | EXPECT_EQ(SystemdMock::instanceName( |
3972 | {"untrusted-type", |
3973 | "com.test.multiple_first_1.2.3", |
3974 | - std::dynamic_pointer_cast<ubuntu::app_launch::jobs::instance::Base>(inst)->getInstanceId(), |
3975 | + std::dynamic_pointer_cast<ubuntu::app_launch::helper_impls::BaseInstance>(inst)->getInstanceId(), |
3976 | 0, |
3977 | {}}), |
3978 | helperStart.begin()->name); |
3979 | @@ -798,7 +808,7 @@ |
3980 | EXPECT_EQ(SystemdMock::instanceName( |
3981 | {"untrusted-type", |
3982 | "com.test.multiple_first_1.2.3", |
3983 | - std::dynamic_pointer_cast<ubuntu::app_launch::jobs::instance::Base>(inst2)->getInstanceId(), |
3984 | + std::dynamic_pointer_cast<ubuntu::app_launch::helper_impls::BaseInstance>(inst2)->getInstanceId(), |
3985 | 0, |
3986 | {}}), |
3987 | helperStart2.begin()->name); |
3988 | @@ -819,7 +829,7 @@ |
3989 | EXPECT_EQ(SystemdMock::instanceName( |
3990 | {"untrusted-type", |
3991 | "com.test.multiple_first_1.2.3", |
3992 | - std::dynamic_pointer_cast<ubuntu::app_launch::jobs::instance::Base>(inst3)->getInstanceId(), |
3993 | + std::dynamic_pointer_cast<ubuntu::app_launch::helper_impls::BaseInstance>(inst3)->getInstanceId(), |
3994 | 0, |
3995 | {}}), |
3996 | helperStart3.begin()->name); |
3997 | @@ -832,7 +842,7 @@ |
3998 | TEST_F(LibUAL, StopHelper) |
3999 | { |
4000 | /* Multi helper */ |
4001 | - auto untrusted = ubuntu::app_launch::Helper::Type::from_raw("untrusted-type"); |
4002 | + auto untrusted = ubuntu::app_launch::Helper::Type::from_raw("untrusted-helper"); |
4003 | |
4004 | auto appid = ubuntu::app_launch::AppID::parse("com.bar_foo_8432.13.1"); |
4005 | auto helper = ubuntu::app_launch::Helper::create(untrusted, appid, registry); |
4006 | @@ -849,7 +859,7 @@ |
4007 | |
4008 | ASSERT_EQ(1u, calls.size()); |
4009 | |
4010 | - EXPECT_EQ(SystemdMock::instanceName({"untrusted-type", "com.bar_foo_8432.13.1", "24034582324132", 0, {}}), |
4011 | + EXPECT_EQ(SystemdMock::instanceName({"untrusted-helper", "com.bar_foo_8432.13.1", "24034582324132", 0, {}}), |
4012 | *calls.begin()); |
4013 | |
4014 | return; |
4015 | @@ -862,7 +872,7 @@ |
4016 | |
4017 | EXPECT_EQ(0, int(notlist.size())); |
4018 | |
4019 | - auto goodhelper = ubuntu::app_launch::Helper::Type::from_raw("untrusted-type"); |
4020 | + auto goodhelper = ubuntu::app_launch::Helper::Type::from_raw("untrusted-helper"); |
4021 | auto goodlist = ubuntu::app_launch::Registry::runningHelpers(goodhelper, registry); |
4022 | |
4023 | ASSERT_EQ(2, int(goodlist.size())); |
4024 | @@ -888,49 +898,48 @@ |
4025 | EXPECT_TRUE(goodlist.back()->instances()[0]->isRunning()); |
4026 | } |
4027 | |
4028 | -typedef struct |
4029 | -{ |
4030 | - int count; |
4031 | - const gchar* appid; |
4032 | - const gchar* type; |
4033 | - const gchar* instance; |
4034 | -} helper_observer_data_t; |
4035 | - |
4036 | -static void helper_observer_cb(const gchar* appid, const gchar* instance, const gchar* type, gpointer user_data) |
4037 | -{ |
4038 | - helper_observer_data_t* data = (helper_observer_data_t*)user_data; |
4039 | - |
4040 | - if (g_strcmp0(data->appid, appid) == 0 && g_strcmp0(data->type, type) == 0 && |
4041 | - g_strcmp0(data->instance, instance) == 0) |
4042 | - { |
4043 | - data->count++; |
4044 | - } |
4045 | -} |
4046 | - |
4047 | TEST_F(LibUAL, StartStopHelperObserver) |
4048 | { |
4049 | - helper_observer_data_t start_data = { |
4050 | - .count = 0, .appid = "com.foo_foo_1.2.3", .type = "my-type-is-scorpio", .instance = nullptr}; |
4051 | - helper_observer_data_t stop_data = { |
4052 | - .count = 0, .appid = "com.bar_bar_44.32", .type = "my-type-is-libra", .instance = "1234"}; |
4053 | - |
4054 | - ASSERT_TRUE(ubuntu_app_launch_observer_add_helper_started(helper_observer_cb, "my-type-is-scorpio", &start_data)); |
4055 | - ASSERT_TRUE(ubuntu_app_launch_observer_add_helper_stop(helper_observer_cb, "my-type-is-libra", &stop_data)); |
4056 | + auto type = ubuntu::app_launch::Helper::Type::from_raw("my-type-is-scorpio"); |
4057 | + auto appid = ubuntu::app_launch::AppID::parse("com.foo_foo_1.2.3"); |
4058 | + |
4059 | + storeForHelper(appid); |
4060 | + |
4061 | + int start_count = 0; |
4062 | + int stop_count = 0; |
4063 | + |
4064 | + ubuntu::app_launch::Registry::helperStarted(type, registry) |
4065 | + .connect([&](const std::shared_ptr<ubuntu::app_launch::Helper>& helper, |
4066 | + const std::shared_ptr<ubuntu::app_launch::Helper::Instance>& inst) { |
4067 | + if (helper->appId() != appid) |
4068 | + { |
4069 | + return; |
4070 | + } |
4071 | + |
4072 | + start_count++; |
4073 | + }); |
4074 | + ubuntu::app_launch::Registry::helperStopped(type, registry) |
4075 | + .connect([&](const std::shared_ptr<ubuntu::app_launch::Helper>& helper, |
4076 | + const std::shared_ptr<ubuntu::app_launch::Helper::Instance>& inst) { |
4077 | + if (helper->appId() != appid) |
4078 | + { |
4079 | + return; |
4080 | + } |
4081 | + |
4082 | + stop_count++; |
4083 | + }); |
4084 | |
4085 | /* Basic start */ |
4086 | - systemd->managerEmitNew(SystemdMock::instanceName({"my-type-is-scorpio", "com.foo_foo_1.2.3", "", 0, {}}), "/"); |
4087 | + systemd->managerEmitNew(SystemdMock::instanceName({"my-type-is-scorpio", "com.foo_foo_1.2.3", "1234", 0, {}}), |
4088 | + "/foo"); |
4089 | |
4090 | - EXPECT_EVENTUALLY_EQ(1, start_data.count); |
4091 | + EXPECT_EVENTUALLY_EQ(1, start_count); |
4092 | |
4093 | /* Basic stop */ |
4094 | - systemd->managerEmitRemoved(SystemdMock::instanceName({"my-type-is-scorpio", "com.foo_foo_1.2.3", "", 0, {}}), "/"); |
4095 | - |
4096 | - EXPECT_EVENTUALLY_EQ(1, stop_data.count); |
4097 | - |
4098 | - /* Remove */ |
4099 | - ASSERT_TRUE( |
4100 | - ubuntu_app_launch_observer_delete_helper_started(helper_observer_cb, "my-type-is-scorpio", &start_data)); |
4101 | - ASSERT_TRUE(ubuntu_app_launch_observer_delete_helper_stop(helper_observer_cb, "my-type-is-libra", &stop_data)); |
4102 | + systemd->managerEmitRemoved(SystemdMock::instanceName({"my-type-is-scorpio", "com.foo_foo_1.2.3", "1234", 0, {}}), |
4103 | + "/foo"); |
4104 | + |
4105 | + EXPECT_EVENTUALLY_EQ(1, stop_count); |
4106 | } |
4107 | |
4108 | // DISABLED: Skipping these tests to not block on bug #1584849 |
4109 | @@ -946,7 +955,10 @@ |
4110 | |
4111 | /* New Systemd Mock */ |
4112 | dbus_test_service_remove_task(service, *systemd); |
4113 | + kill(dbus_test_process_get_pid(*systemd), SIGTERM); |
4114 | + EXPECT_EVENTUALLY_FUNC_EQ(DBUS_TEST_TASK_STATE_FINISHED, systemd->stateFunc()); |
4115 | systemd.reset(); |
4116 | + |
4117 | auto systemd2 = std::make_shared<SystemdMock>( |
4118 | std::list<SystemdMock::Instance>{ |
4119 | {"application-click", "com.test.good_application_1.2.3", {}, spew.pid(), {spew.pid()}}}, |
4120 | @@ -1032,6 +1044,7 @@ |
4121 | |
4122 | TEST_F(LibUAL, MultiPause) |
4123 | { |
4124 | + auto appid = ubuntu::app_launch::AppID::find(registry, "single"); |
4125 | g_setenv("UBUNTU_APP_LAUNCH_OOM_PROC_PATH", CMAKE_BINARY_DIR "/libual-proc", 1); |
4126 | |
4127 | /* Setup A TON OF spew */ |
4128 | @@ -1042,18 +1055,32 @@ |
4129 | |
4130 | /* New Systemd Mock */ |
4131 | dbus_test_service_remove_task(service, *systemd); |
4132 | + kill(dbus_test_process_get_pid(*systemd), SIGTERM); |
4133 | + EXPECT_EVENTUALLY_FUNC_EQ(DBUS_TEST_TASK_STATE_FINISHED, systemd->stateFunc()); |
4134 | systemd.reset(); |
4135 | - std::vector<pid_t> spewpids; |
4136 | - std::transform(spews.begin(), spews.end(), spewpids.begin(), [](SpewMaster& spew) { return spew.pid(); }); |
4137 | + |
4138 | + std::vector<pid_t> spewpids{int(spews.size())}; |
4139 | + for (const auto& spew : spews) |
4140 | + { |
4141 | + spewpids.push_back(spew.pid()); |
4142 | + } |
4143 | auto systemd2 = std::make_shared<SystemdMock>( |
4144 | - std::list<SystemdMock::Instance>{ |
4145 | - {"application-click", "com.test.good_application_1.2.3", {}, spews.begin()->pid(), spewpids}}, |
4146 | + std::list<SystemdMock::Instance>{{"application-legacy", "single", {}, spews.begin()->pid(), spewpids}}, |
4147 | CGROUP_DIR); |
4148 | |
4149 | + /* Add mocks */ |
4150 | + dbus_test_service_add_task(service, *systemd2); |
4151 | + dbus_test_service_add_task(service, *zgmock); |
4152 | + dbus_test_task_run(*systemd2); |
4153 | + dbus_test_task_run(*zgmock); |
4154 | + |
4155 | /* Give things a chance to start */ |
4156 | EXPECT_EVENTUALLY_FUNC_EQ(DBUS_TEST_TASK_STATE_RUNNING, systemd2->stateFunc()); |
4157 | EXPECT_EVENTUALLY_FUNC_EQ(DBUS_TEST_TASK_STATE_RUNNING, zgmock->stateFunc()); |
4158 | |
4159 | + /* Resetup the registry with the new systemd */ |
4160 | + registry = std::make_shared<ubuntu::app_launch::Registry>(); |
4161 | + |
4162 | /* Setup signal handling */ |
4163 | guint paused_count = 0; |
4164 | guint resumed_count = 0; |
4165 | @@ -1078,10 +1105,10 @@ |
4166 | }); |
4167 | |
4168 | /* Get our app object */ |
4169 | - auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3"); |
4170 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
4171 | |
4172 | - ASSERT_EQ(1, int(app->instances().size())); |
4173 | + ASSERT_NE(nullptr, app); |
4174 | + ASSERT_EQ(1u, app->instances().size()); |
4175 | |
4176 | auto instance = app->instances()[0]; |
4177 | |
4178 | @@ -1150,10 +1177,10 @@ |
4179 | ASSERT_TRUE(g_file_set_contents(oomadjfile, "0", -1, NULL)); |
4180 | |
4181 | /* Get our app object */ |
4182 | - auto appid = ubuntu::app_launch::AppID::find(registry, "com.test.good_application_1.2.3"); |
4183 | + auto appid = ubuntu::app_launch::AppID::find(registry, "single"); |
4184 | auto app = ubuntu::app_launch::Application::create(appid, registry); |
4185 | |
4186 | - ASSERT_EQ(1, int(app->instances().size())); |
4187 | + ASSERT_EQ(1u, app->instances().size()); |
4188 | |
4189 | auto instance = app->instances()[0]; |
4190 | |
4191 | @@ -1270,76 +1297,99 @@ |
4192 | return; |
4193 | } |
4194 | |
4195 | -#if 0 |
4196 | -/* Need to change as helpers change to not use Upstart features */ |
4197 | +/* Hardcore socket stuff */ |
4198 | +#include <sys/socket.h> |
4199 | +#include <sys/types.h> |
4200 | +#include <sys/un.h> |
4201 | + |
4202 | TEST_F(LibUAL, SetExec) |
4203 | { |
4204 | - DbusTestDbusMockObject* obj = |
4205 | - dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL); |
4206 | - |
4207 | - const char* exec = "lets exec this"; |
4208 | - |
4209 | - g_setenv("UPSTART_JOB", "fubar", TRUE); |
4210 | - g_unsetenv("UBUNTU_APP_LAUNCH_DEMANGLE_NAME"); |
4211 | - EXPECT_TRUE(ubuntu_app_launch_helper_set_exec(exec, NULL)); |
4212 | - |
4213 | - guint len = 0; |
4214 | - const DbusTestDbusMockCall* calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "SetEnv", &len, NULL); |
4215 | - ASSERT_NE(nullptr, calls); |
4216 | - ASSERT_EQ(1u, len); |
4217 | - |
4218 | - gchar* appexecstr = g_strdup_printf("APP_EXEC=%s", exec); |
4219 | - GVariant* appexecenv = g_variant_get_child_value(calls[0].params, 1); |
4220 | - EXPECT_STREQ(appexecstr, g_variant_get_string(appexecenv, nullptr)); |
4221 | - g_variant_unref(appexecenv); |
4222 | - g_free(appexecstr); |
4223 | - |
4224 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL)); |
4225 | - |
4226 | - /* Now check for the demangler */ |
4227 | - g_setenv("UBUNTU_APP_LAUNCH_DEMANGLE_NAME", g_dbus_connection_get_unique_name(bus), TRUE); |
4228 | - EXPECT_TRUE(ubuntu_app_launch_helper_set_exec(exec, NULL)); |
4229 | - |
4230 | - calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "SetEnv", &len, NULL); |
4231 | - ASSERT_NE(nullptr, calls); |
4232 | - ASSERT_EQ(1u, len); |
4233 | - |
4234 | - gchar* demangleexecstr = g_strdup_printf("APP_EXEC=%s %s", SOCKET_DEMANGLER_INSTALL, exec); |
4235 | - appexecenv = g_variant_get_child_value(calls[0].params, 1); |
4236 | - EXPECT_STREQ(demangleexecstr, g_variant_get_string(appexecenv, nullptr)); |
4237 | - g_variant_unref(appexecenv); |
4238 | - g_free(demangleexecstr); |
4239 | - |
4240 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL)); |
4241 | - |
4242 | - /* Now check for the directory */ |
4243 | - g_setenv("UBUNTU_APP_LAUNCH_DEMANGLE_NAME", g_dbus_connection_get_unique_name(bus), TRUE); |
4244 | - EXPECT_TRUE(ubuntu_app_launch_helper_set_exec(exec, "/not/a/real/directory")); |
4245 | - |
4246 | - calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "SetEnv", &len, NULL); |
4247 | - ASSERT_NE(nullptr, calls); |
4248 | - EXPECT_EQ(2u, len); |
4249 | - |
4250 | - appexecenv = g_variant_get_child_value(calls[1].params, 1); |
4251 | - EXPECT_STREQ("APP_DIR=/not/a/real/directory", g_variant_get_string(appexecenv, nullptr)); |
4252 | - g_variant_unref(appexecenv); |
4253 | - |
4254 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL)); |
4255 | + /* Create a socket */ |
4256 | + class SmartSocket |
4257 | + { |
4258 | + public: |
4259 | + int fd; |
4260 | + SmartSocket() |
4261 | + : fd(socket(AF_UNIX, SOCK_STREAM, 0)) |
4262 | + { |
4263 | + } |
4264 | + ~SmartSocket() |
4265 | + { |
4266 | + close(fd); |
4267 | + } |
4268 | + }; |
4269 | + SmartSocket sock; |
4270 | + ASSERT_NE(0, sock.fd); |
4271 | + |
4272 | + std::string socketname{"/ual-setexec-test-12445343"}; |
4273 | + |
4274 | + struct sockaddr_un socketaddr = {0}; |
4275 | + socketaddr.sun_family = AF_UNIX; |
4276 | + strncpy(socketaddr.sun_path, socketname.c_str(), sizeof(socketaddr.sun_path) - 1); |
4277 | + socketaddr.sun_path[0] = 0; |
4278 | + |
4279 | + ASSERT_EQ(0, bind(sock.fd, (const struct sockaddr*)&socketaddr, sizeof(struct sockaddr_un))); |
4280 | + listen(sock.fd, 1); /* 1 is the number of people who can connect */ |
4281 | + |
4282 | + setenv("UBUNTU_APP_LAUNCH_HELPER_EXECTOOL_SETEXEC_SOCKET", socketname.c_str(), 1); |
4283 | + |
4284 | + std::promise<std::vector<std::string>> socketpromise; |
4285 | + std::thread socketreader([&]() { |
4286 | + std::vector<std::string> socketvals; |
4287 | + |
4288 | + int readsocket = accept(sock.fd, NULL, NULL); |
4289 | + |
4290 | + /* Keeping this similar to the helper-helper code as that's what |
4291 | + * we're running against. Not making it C++-style. */ |
4292 | + char readbuf[2048] = {0}; |
4293 | + int thisread = 0; |
4294 | + int amountread = 0; |
4295 | + while ((thisread = read(readsocket, readbuf + amountread, 2048 - amountread)) > 0) |
4296 | + { |
4297 | + amountread += thisread; |
4298 | + |
4299 | + if (amountread == 2048) |
4300 | + { |
4301 | + try |
4302 | + { |
4303 | + throw std::runtime_error{"Read too many bytes from socket"}; |
4304 | + } |
4305 | + catch (...) |
4306 | + { |
4307 | + socketpromise.set_exception(std::current_exception()); |
4308 | + } |
4309 | + return; |
4310 | + } |
4311 | + } |
4312 | + |
4313 | + close(readsocket); |
4314 | + |
4315 | + /* Parse data */ |
4316 | + if (amountread > 0) |
4317 | + { |
4318 | + char* startvar = readbuf; |
4319 | + |
4320 | + do |
4321 | + { |
4322 | + socketvals.emplace_back(std::string(startvar)); |
4323 | + |
4324 | + startvar = startvar + strlen(startvar) + 1; |
4325 | + } while (startvar < readbuf + amountread); |
4326 | + } |
4327 | + |
4328 | + /* Read socket */ |
4329 | + socketpromise.set_value(socketvals); |
4330 | + }); |
4331 | + socketreader.detach(); /* avoid thread cleanup code when we don't really care */ |
4332 | + |
4333 | + std::vector<std::string> execList{"Foo", "Bar", "Really really really long value", "Another value"}; |
4334 | + ubuntu::app_launch::Helper::setExec(execList); |
4335 | + |
4336 | + EXPECT_EQ(execList, socketpromise.get_future().get()); |
4337 | } |
4338 | -#endif |
4339 | |
4340 | TEST_F(LibUAL, AppInfo) |
4341 | { |
4342 | - g_setenv("TEST_CLICK_DB", "click-db-dir", TRUE); |
4343 | - g_setenv("TEST_CLICK_USER", "test-user", TRUE); |
4344 | - |
4345 | - /* Correct values from a click */ |
4346 | - auto appid = ubuntu::app_launch::AppID::parse("com.test.good_application_1.2.4"); |
4347 | - auto app = ubuntu::app_launch::Application::create(appid, registry); |
4348 | - |
4349 | - EXPECT_TRUE((bool)app->info()); |
4350 | - EXPECT_EQ("Application", app->info()->name().value()); |
4351 | - |
4352 | /* Correct values from a legacy */ |
4353 | auto barid = ubuntu::app_launch::AppID::find(registry, "bar"); |
4354 | EXPECT_THROW(ubuntu::app_launch::Application::create(barid, registry), std::runtime_error); |
4355 | |
4356 | === modified file 'tests/libual-test.cc' |
4357 | --- tests/libual-test.cc 2017-02-15 15:10:07 +0000 |
4358 | +++ tests/libual-test.cc 2017-03-21 03:26:40 +0000 |
4359 | @@ -20,6 +20,7 @@ |
4360 | #include <fcntl.h> |
4361 | #include <future> |
4362 | #include <gio/gio.h> |
4363 | +#include <glib/gstdio.h> |
4364 | #include <gtest/gtest.h> |
4365 | #include <libdbustest/dbus-test.h> |
4366 | #include <thread> |
4367 | @@ -30,340 +31,164 @@ |
4368 | #include "registry.h" |
4369 | #include "ubuntu-app-launch.h" |
4370 | |
4371 | +#include "eventually-fixture.h" |
4372 | #include "libertine-service.h" |
4373 | -#include "eventually-fixture.h" |
4374 | #include "mir-mock.h" |
4375 | +#include "snapd-mock.h" |
4376 | +#include "systemd-mock.h" |
4377 | + |
4378 | +#define LOCAL_SNAPD_TEST_SOCKET (SNAPD_TEST_SOCKET "-libual-test") |
4379 | +#define CGROUP_DIR (CMAKE_BINARY_DIR "/systemd-libual-cgroups") |
4380 | |
4381 | class LibUAL : public EventuallyFixture |
4382 | { |
4383 | - protected: |
4384 | - DbusTestService * service = NULL; |
4385 | - DbusTestDbusMock * mock = NULL; |
4386 | - DbusTestDbusMock * cgmock = NULL; |
4387 | - std::shared_ptr<LibertineService> libertine; |
4388 | - GDBusConnection * bus = NULL; |
4389 | - std::string last_focus_appid; |
4390 | - std::string last_resume_appid; |
4391 | - guint resume_timeout = 0; |
4392 | - |
4393 | - private: |
4394 | - static void focus_cb (const gchar * appid, gpointer user_data) { |
4395 | - g_debug("Focus Callback: %s", appid); |
4396 | - LibUAL * _this = static_cast<LibUAL *>(user_data); |
4397 | - _this->last_focus_appid = appid; |
4398 | - } |
4399 | - |
4400 | - static void resume_cb (const gchar * appid, gpointer user_data) { |
4401 | - g_debug("Resume Callback: %s", appid); |
4402 | - LibUAL * _this = static_cast<LibUAL *>(user_data); |
4403 | - _this->last_resume_appid = appid; |
4404 | - |
4405 | - if (_this->resume_timeout > 0) { |
4406 | - _this->pause(_this->resume_timeout); |
4407 | - } |
4408 | - } |
4409 | - |
4410 | - protected: |
4411 | - /* Useful debugging stuff, but not on by default. You really want to |
4412 | - not get all this noise typically */ |
4413 | - void debugConnection() { |
4414 | - if (true) return; |
4415 | - |
4416 | - DbusTestBustle * bustle = dbus_test_bustle_new("test.bustle"); |
4417 | - dbus_test_service_add_task(service, DBUS_TEST_TASK(bustle)); |
4418 | - g_object_unref(bustle); |
4419 | - |
4420 | - DbusTestProcess * monitor = dbus_test_process_new("dbus-monitor"); |
4421 | - dbus_test_service_add_task(service, DBUS_TEST_TASK(monitor)); |
4422 | - g_object_unref(monitor); |
4423 | - } |
4424 | - |
4425 | - virtual void SetUp() { |
4426 | - /* Click DB test mode */ |
4427 | - g_setenv("TEST_CLICK_DB", "click-db-dir", TRUE); |
4428 | - g_setenv("TEST_CLICK_USER", "test-user", TRUE); |
4429 | - |
4430 | - gchar * linkfarmpath = g_build_filename(CMAKE_SOURCE_DIR, "link-farm", NULL); |
4431 | - g_setenv("UBUNTU_APP_LAUNCH_LINK_FARM", linkfarmpath, TRUE); |
4432 | - g_free(linkfarmpath); |
4433 | - |
4434 | - g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE); |
4435 | - g_setenv("XDG_CACHE_HOME", CMAKE_SOURCE_DIR "/libertine-data", TRUE); |
4436 | - g_setenv("XDG_DATA_HOME", CMAKE_SOURCE_DIR "/libertine-home", TRUE); |
4437 | - |
4438 | - g_setenv("UBUNTU_APP_LAUNCH_SNAPD_SOCKET", "/this/should/not/exist", TRUE); |
4439 | - g_setenv("UBUNTU_APP_LAUNCH_SYSTEMD_PATH", "/this/should/not/exist", TRUE); |
4440 | - |
4441 | - service = dbus_test_service_new(NULL); |
4442 | - |
4443 | - debugConnection(); |
4444 | - |
4445 | - mock = dbus_test_dbus_mock_new("com.ubuntu.Upstart"); |
4446 | - |
4447 | - DbusTestDbusMockObject * obj = dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL); |
4448 | - |
4449 | - dbus_test_dbus_mock_object_add_method(mock, obj, |
4450 | - "EmitEvent", |
4451 | - G_VARIANT_TYPE("(sasb)"), |
4452 | - NULL, |
4453 | - "", |
4454 | - NULL); |
4455 | - |
4456 | - dbus_test_dbus_mock_object_add_method(mock, obj, |
4457 | - "GetJobByName", |
4458 | - G_VARIANT_TYPE("s"), |
4459 | - G_VARIANT_TYPE("o"), |
4460 | - "if args[0] == 'application-click':\n" |
4461 | - " ret = dbus.ObjectPath('/com/test/application_click')\n" |
4462 | - "elif args[0] == 'application-legacy':\n" |
4463 | - " ret = dbus.ObjectPath('/com/test/application_legacy')\n" |
4464 | - "elif args[0] == 'untrusted-helper':\n" |
4465 | - " ret = dbus.ObjectPath('/com/test/untrusted/helper')\n", |
4466 | - NULL); |
4467 | - |
4468 | - dbus_test_dbus_mock_object_add_method(mock, obj, |
4469 | - "SetEnv", |
4470 | - G_VARIANT_TYPE("(assb)"), |
4471 | - NULL, |
4472 | - "", |
4473 | - NULL); |
4474 | - |
4475 | - /* Click App */ |
4476 | - DbusTestDbusMockObject * jobobj = dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL); |
4477 | - |
4478 | - dbus_test_dbus_mock_object_add_method(mock, jobobj, |
4479 | - "Start", |
4480 | - G_VARIANT_TYPE("(asb)"), |
4481 | - NULL, |
4482 | - "if 'APP_ID=com.test.good_application_1.2.3' in args[0]:" |
4483 | - " raise dbus.exceptions.DBusException('Foo running', name='com.ubuntu.Upstart0_6.Error.AlreadyStarted')", |
4484 | - NULL); |
4485 | - |
4486 | - dbus_test_dbus_mock_object_add_method(mock, jobobj, |
4487 | - "Stop", |
4488 | - G_VARIANT_TYPE("(asb)"), |
4489 | - NULL, |
4490 | - "", |
4491 | - NULL); |
4492 | - |
4493 | - dbus_test_dbus_mock_object_add_method(mock, jobobj, |
4494 | - "GetAllInstances", |
4495 | - NULL, |
4496 | - G_VARIANT_TYPE("ao"), |
4497 | - "ret = [ dbus.ObjectPath('/com/test/app_instance') ]", |
4498 | - NULL); |
4499 | - |
4500 | - dbus_test_dbus_mock_object_add_method(mock, |
4501 | - jobobj, |
4502 | - "GetInstanceByName", |
4503 | - G_VARIANT_TYPE_STRING, |
4504 | - G_VARIANT_TYPE("o"), |
4505 | - "ret = dbus.ObjectPath('/com/test/app_instance')", |
4506 | - NULL); |
4507 | - |
4508 | - DbusTestDbusMockObject * instobj = dbus_test_dbus_mock_get_object(mock, "/com/test/app_instance", "com.ubuntu.Upstart0_6.Instance", NULL); |
4509 | - dbus_test_dbus_mock_object_add_property(mock, instobj, |
4510 | - "name", |
4511 | - G_VARIANT_TYPE_STRING, |
4512 | - g_variant_new_string("com.test.good_application_1.2.3"), |
4513 | - NULL); |
4514 | - gchar * process_var = g_strdup_printf("[('main', %d)]", getpid()); |
4515 | - dbus_test_dbus_mock_object_add_property(mock, instobj, |
4516 | - "processes", |
4517 | - G_VARIANT_TYPE("a(si)"), |
4518 | - g_variant_new_parsed(process_var), |
4519 | - NULL); |
4520 | - g_free(process_var); |
4521 | - |
4522 | - /* Legacy App */ |
4523 | - DbusTestDbusMockObject * ljobobj = dbus_test_dbus_mock_get_object(mock, "/com/test/application_legacy", "com.ubuntu.Upstart0_6.Job", NULL); |
4524 | - |
4525 | - dbus_test_dbus_mock_object_add_method(mock, ljobobj, |
4526 | - "Start", |
4527 | - G_VARIANT_TYPE("(asb)"), |
4528 | - NULL, |
4529 | - "", |
4530 | - NULL); |
4531 | - |
4532 | - dbus_test_dbus_mock_object_add_method(mock, ljobobj, |
4533 | - "Stop", |
4534 | - G_VARIANT_TYPE("(asb)"), |
4535 | - NULL, |
4536 | - "", |
4537 | - NULL); |
4538 | - |
4539 | - dbus_test_dbus_mock_object_add_method(mock, ljobobj, |
4540 | - "GetAllInstances", |
4541 | - NULL, |
4542 | - G_VARIANT_TYPE("ao"), |
4543 | - "ret = [ dbus.ObjectPath('/com/test/legacy_app_instance'), dbus.ObjectPath('/com/test/legacy_app_instance2')]", |
4544 | - NULL); |
4545 | - |
4546 | - dbus_test_dbus_mock_object_add_method(mock, |
4547 | - ljobobj, |
4548 | - "GetInstanceByName", |
4549 | - G_VARIANT_TYPE_STRING, |
4550 | - G_VARIANT_TYPE("o"), |
4551 | - "if args[0] == 'multiple-2342345':\n" |
4552 | - " ret = dbus.ObjectPath('/com/test/legacy_app_instance')\n" |
4553 | - "elif args[0] == 'single-':\n" |
4554 | - " ret = dbus.ObjectPath('/com/test/legacy_app_instance2')", |
4555 | - NULL); |
4556 | - |
4557 | - DbusTestDbusMockObject * linstobj = dbus_test_dbus_mock_get_object(mock, "/com/test/legacy_app_instance", "com.ubuntu.Upstart0_6.Instance", NULL); |
4558 | - dbus_test_dbus_mock_object_add_property(mock, linstobj, |
4559 | - "name", |
4560 | - G_VARIANT_TYPE_STRING, |
4561 | - g_variant_new_string("multiple-2342345"), |
4562 | - NULL); |
4563 | - dbus_test_dbus_mock_object_add_property(mock, linstobj, |
4564 | - "processes", |
4565 | - G_VARIANT_TYPE("a(si)"), |
4566 | - g_variant_new_parsed("[('main', 5678)]"), |
4567 | - NULL); |
4568 | - |
4569 | - DbusTestDbusMockObject* linstobj2 = dbus_test_dbus_mock_get_object(mock, "/com/test/legacy_app_instance2", |
4570 | - "com.ubuntu.Upstart0_6.Instance", NULL); |
4571 | - dbus_test_dbus_mock_object_add_property(mock, linstobj2, "name", G_VARIANT_TYPE_STRING, |
4572 | - g_variant_new_string("single-"), NULL); |
4573 | - dbus_test_dbus_mock_object_add_property(mock, linstobj2, "processes", G_VARIANT_TYPE("a(si)"), |
4574 | - g_variant_new_parsed("[('main', 5678)]"), NULL); |
4575 | - |
4576 | - /* Untrusted Helper */ |
4577 | - DbusTestDbusMockObject * uhelperobj = dbus_test_dbus_mock_get_object(mock, "/com/test/untrusted/helper", "com.ubuntu.Upstart0_6.Job", NULL); |
4578 | - |
4579 | - dbus_test_dbus_mock_object_add_method(mock, uhelperobj, |
4580 | - "Start", |
4581 | - G_VARIANT_TYPE("(asb)"), |
4582 | - NULL, |
4583 | - "", |
4584 | - NULL); |
4585 | - |
4586 | - dbus_test_dbus_mock_object_add_method(mock, uhelperobj, |
4587 | - "Stop", |
4588 | - G_VARIANT_TYPE("(asb)"), |
4589 | - NULL, |
4590 | - "", |
4591 | - NULL); |
4592 | - |
4593 | - dbus_test_dbus_mock_object_add_method(mock, uhelperobj, |
4594 | - "GetAllInstances", |
4595 | - NULL, |
4596 | - G_VARIANT_TYPE("ao"), |
4597 | - "ret = [ dbus.ObjectPath('/com/test/untrusted/helper/instance'), dbus.ObjectPath('/com/test/untrusted/helper/multi_instance') ]", |
4598 | - NULL); |
4599 | - |
4600 | - DbusTestDbusMockObject * uhelperinstance = dbus_test_dbus_mock_get_object(mock, "/com/test/untrusted/helper/instance", "com.ubuntu.Upstart0_6.Instance", NULL); |
4601 | - dbus_test_dbus_mock_object_add_property(mock, uhelperinstance, |
4602 | - "name", |
4603 | - G_VARIANT_TYPE_STRING, |
4604 | - g_variant_new_string("untrusted-type::com.foo_bar_43.23.12"), |
4605 | - NULL); |
4606 | - |
4607 | - DbusTestDbusMockObject * unhelpermulti = dbus_test_dbus_mock_get_object(mock, "/com/test/untrusted/helper/multi_instance", "com.ubuntu.Upstart0_6.Instance", NULL); |
4608 | - dbus_test_dbus_mock_object_add_property(mock, unhelpermulti, |
4609 | - "name", |
4610 | - G_VARIANT_TYPE_STRING, |
4611 | - g_variant_new_string("untrusted-type:24034582324132:com.bar_foo_8432.13.1"), |
4612 | - NULL); |
4613 | - |
4614 | - /* Create the cgroup manager mock */ |
4615 | - cgmock = dbus_test_dbus_mock_new("org.test.cgmock"); |
4616 | - g_setenv("UBUNTU_APP_LAUNCH_CG_MANAGER_NAME", "org.test.cgmock", TRUE); |
4617 | - |
4618 | - DbusTestDbusMockObject * cgobject = dbus_test_dbus_mock_get_object(cgmock, "/org/linuxcontainers/cgmanager", "org.linuxcontainers.cgmanager0_0", NULL); |
4619 | - dbus_test_dbus_mock_object_add_method(cgmock, cgobject, |
4620 | - "GetTasksRecursive", |
4621 | - G_VARIANT_TYPE("(ss)"), |
4622 | - G_VARIANT_TYPE("ai"), |
4623 | - "ret = [100, 200, 300]", |
4624 | - NULL); |
4625 | - |
4626 | - /* Put it together */ |
4627 | - dbus_test_service_add_task(service, DBUS_TEST_TASK(mock)); |
4628 | - dbus_test_service_add_task(service, DBUS_TEST_TASK(cgmock)); |
4629 | - |
4630 | - /* Add in Libertine */ |
4631 | - libertine = std::make_shared<LibertineService>(); |
4632 | - dbus_test_service_add_task(service, *libertine); |
4633 | - dbus_test_service_add_task(service, libertine->waitTask()); |
4634 | - |
4635 | - dbus_test_service_start_tasks(service); |
4636 | - |
4637 | - bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); |
4638 | - g_dbus_connection_set_exit_on_close(bus, FALSE); |
4639 | - g_object_add_weak_pointer(G_OBJECT(bus), (gpointer *)&bus); |
4640 | - |
4641 | - /* Make sure we pretend the CG manager is just on our bus */ |
4642 | - g_setenv("UBUNTU_APP_LAUNCH_CG_MANAGER_SESSION_BUS", "YES", TRUE); |
4643 | - |
4644 | - ASSERT_TRUE(ubuntu_app_launch_observer_add_app_focus(focus_cb, this)); |
4645 | - ASSERT_TRUE(ubuntu_app_launch_observer_add_app_resume(resume_cb, this)); |
4646 | - } |
4647 | - |
4648 | - virtual void TearDown() { |
4649 | - ubuntu_app_launch_observer_delete_app_focus(focus_cb, this); |
4650 | - ubuntu_app_launch_observer_delete_app_resume(resume_cb, this); |
4651 | - |
4652 | - ubuntu::app_launch::Registry::clearDefault(); |
4653 | - |
4654 | - libertine.reset(); |
4655 | - g_clear_object(&mock); |
4656 | - g_clear_object(&cgmock); |
4657 | - g_clear_object(&service); |
4658 | - |
4659 | - g_object_unref(bus); |
4660 | - |
4661 | - ASSERT_EVENTUALLY_EQ(nullptr, bus); |
4662 | - } |
4663 | - |
4664 | - GVariant * find_env (GVariant * env_array, const gchar * var) { |
4665 | - unsigned int i; |
4666 | - GVariant * retval = nullptr; |
4667 | - |
4668 | - for (i = 0; i < g_variant_n_children(env_array); i++) { |
4669 | - GVariant * child = g_variant_get_child_value(env_array, i); |
4670 | - const gchar * envvar = g_variant_get_string(child, nullptr); |
4671 | - |
4672 | - if (g_str_has_prefix(envvar, var)) { |
4673 | - if (retval != nullptr) { |
4674 | - g_warning("Found the env var more than once!"); |
4675 | - g_variant_unref(retval); |
4676 | - return nullptr; |
4677 | - } |
4678 | - |
4679 | - retval = child; |
4680 | - } else { |
4681 | - g_variant_unref(child); |
4682 | - } |
4683 | - } |
4684 | - |
4685 | - if (!retval) { |
4686 | - gchar * envstr = g_variant_print(env_array, FALSE); |
4687 | - g_warning("Unable to find '%s' in '%s'", var, envstr); |
4688 | - g_free(envstr); |
4689 | - } |
4690 | - |
4691 | - return retval; |
4692 | - } |
4693 | - |
4694 | - bool check_env (GVariant * env_array, const gchar * var, const gchar * value) { |
4695 | - bool found = false; |
4696 | - GVariant * val = find_env(env_array, var); |
4697 | - if (val == nullptr) |
4698 | - return false; |
4699 | - |
4700 | - const gchar * envvar = g_variant_get_string(val, nullptr); |
4701 | - |
4702 | - gchar * combined = g_strdup_printf("%s=%s", var, value); |
4703 | - if (g_strcmp0(envvar, combined) == 0) { |
4704 | - found = true; |
4705 | - } |
4706 | - |
4707 | - g_variant_unref(val); |
4708 | - |
4709 | - return found; |
4710 | - } |
4711 | +protected: |
4712 | + DbusTestService *service = NULL; |
4713 | + DbusTestDbusMock *mock = NULL; |
4714 | + DbusTestDbusMock *cgmock = NULL; |
4715 | + std::shared_ptr<LibertineService> libertine; |
4716 | + std::shared_ptr<SystemdMock> systemd; |
4717 | + GDBusConnection *bus = NULL; |
4718 | + std::string last_focus_appid; |
4719 | + std::string last_resume_appid; |
4720 | + guint resume_timeout = 0; |
4721 | + |
4722 | +private: |
4723 | + static void focus_cb(const gchar *appid, gpointer user_data) |
4724 | + { |
4725 | + g_debug("Focus Callback: %s", appid); |
4726 | + LibUAL *_this = static_cast<LibUAL *>(user_data); |
4727 | + _this->last_focus_appid = appid; |
4728 | + } |
4729 | + |
4730 | + static void resume_cb(const gchar *appid, gpointer user_data) |
4731 | + { |
4732 | + g_debug("Resume Callback: %s", appid); |
4733 | + LibUAL *_this = static_cast<LibUAL *>(user_data); |
4734 | + _this->last_resume_appid = appid; |
4735 | + |
4736 | + if (_this->resume_timeout > 0) |
4737 | + { |
4738 | + _this->pause(_this->resume_timeout); |
4739 | + } |
4740 | + } |
4741 | + |
4742 | +protected: |
4743 | + /* Useful debugging stuff, but not on by default. You really want to |
4744 | + not get all this noise typically */ |
4745 | + void debugConnection() |
4746 | + { |
4747 | + if (true) |
4748 | + return; |
4749 | + |
4750 | + DbusTestBustle *bustle = dbus_test_bustle_new("test.bustle"); |
4751 | + dbus_test_service_add_task(service, DBUS_TEST_TASK(bustle)); |
4752 | + g_object_unref(bustle); |
4753 | + |
4754 | + DbusTestProcess *monitor = dbus_test_process_new("dbus-monitor"); |
4755 | + dbus_test_service_add_task(service, DBUS_TEST_TASK(monitor)); |
4756 | + g_object_unref(monitor); |
4757 | + } |
4758 | + |
4759 | + virtual void SetUp() |
4760 | + { |
4761 | + g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE); |
4762 | + g_setenv("XDG_CACHE_HOME", CMAKE_SOURCE_DIR "/libertine-data", TRUE); |
4763 | + g_setenv("XDG_DATA_HOME", CMAKE_SOURCE_DIR "/libertine-home", TRUE); |
4764 | + |
4765 | + g_setenv("UBUNTU_APP_LAUNCH_SNAPD_SOCKET", LOCAL_SNAPD_TEST_SOCKET, TRUE); |
4766 | + g_setenv("UBUNTU_APP_LAUNCH_SNAP_BASEDIR", SNAP_BASEDIR, TRUE); |
4767 | + g_setenv("UBUNTU_APP_LAUNCH_DISABLE_SNAPD_TIMEOUT", "You betcha!", TRUE); |
4768 | + |
4769 | + g_setenv("UBUNTU_APP_LAUNCH_SYSTEMD_PATH", "/this/should/not/exist", TRUE); |
4770 | + g_setenv("UBUNTU_APP_LAUNCH_SYSTEMD_CGROUP_ROOT", CGROUP_DIR, TRUE); |
4771 | + |
4772 | + g_unlink(LOCAL_SNAPD_TEST_SOCKET); |
4773 | + |
4774 | + service = dbus_test_service_new(NULL); |
4775 | + |
4776 | + debugConnection(); |
4777 | + |
4778 | + systemd = std::make_shared<SystemdMock>( |
4779 | + std::list<SystemdMock::Instance>{ |
4780 | + {"application-snap", "unity8-package_foo_x123", {}, getpid(), {100, 200, 300}}, |
4781 | + {"application-legacy", "multiple", "2342345", 5678, {100, 200, 300}}, |
4782 | + {"application-legacy", "single", {}, getpid(), {getpid()}}, |
4783 | + {"untrusted-helper", "com.foo_bar_43.23.12", {}, 1, {100, 200, 300}}, |
4784 | + {"untrusted-helper", "com.bar_foo_8432.13.1", "24034582324132", 1, {100, 200, 300}}}, |
4785 | + CGROUP_DIR); |
4786 | + |
4787 | + /* Put it together */ |
4788 | + dbus_test_service_add_task(service, *systemd); |
4789 | + |
4790 | + /* Add in Libertine */ |
4791 | + libertine = std::make_shared<LibertineService>(); |
4792 | + dbus_test_service_add_task(service, *libertine); |
4793 | + dbus_test_service_add_task(service, libertine->waitTask()); |
4794 | + |
4795 | + dbus_test_service_start_tasks(service); |
4796 | + |
4797 | + bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); |
4798 | + g_dbus_connection_set_exit_on_close(bus, FALSE); |
4799 | + g_object_add_weak_pointer(G_OBJECT(bus), (gpointer *)&bus); |
4800 | + |
4801 | + ASSERT_TRUE(ubuntu_app_launch_observer_add_app_focus(focus_cb, this)); |
4802 | + ASSERT_TRUE(ubuntu_app_launch_observer_add_app_resume(resume_cb, this)); |
4803 | + } |
4804 | + |
4805 | + virtual void TearDown() |
4806 | + { |
4807 | + ubuntu_app_launch_observer_delete_app_focus(focus_cb, this); |
4808 | + ubuntu_app_launch_observer_delete_app_resume(resume_cb, this); |
4809 | + |
4810 | + ubuntu::app_launch::Registry::clearDefault(); |
4811 | + |
4812 | + systemd.reset(); |
4813 | + libertine.reset(); |
4814 | + g_clear_object(&service); |
4815 | + |
4816 | + g_object_unref(bus); |
4817 | + |
4818 | + ASSERT_EVENTUALLY_EQ(nullptr, bus); |
4819 | + |
4820 | + g_unlink(LOCAL_SNAPD_TEST_SOCKET); |
4821 | + } |
4822 | + |
4823 | + static std::string find_env(std::set<std::string> &envs, std::string var) |
4824 | + { |
4825 | + auto iter = |
4826 | + std::find_if(envs.begin(), envs.end(), [var](std::string value) { return split_env(value).first == var; }); |
4827 | + |
4828 | + if (iter == envs.end()) |
4829 | + { |
4830 | + return {}; |
4831 | + } |
4832 | + else |
4833 | + { |
4834 | + return *iter; |
4835 | + } |
4836 | + } |
4837 | + |
4838 | + static std::pair<std::string, std::string> split_env(const std::string &env) |
4839 | + { |
4840 | + auto eq = std::find(env.begin(), env.end(), '='); |
4841 | + if (eq == env.end()) |
4842 | + { |
4843 | + throw std::runtime_error{"Environment value is invalid: " + env}; |
4844 | + } |
4845 | + |
4846 | + return std::make_pair(std::string(env.begin(), eq), std::string(eq + 1, env.end())); |
4847 | + } |
4848 | + |
4849 | + static bool check_env(std::set<std::string> &envs, const std::string &key, const std::string &value) |
4850 | + { |
4851 | + auto val = find_env(envs, key); |
4852 | + if (val.empty()) |
4853 | + { |
4854 | + return false; |
4855 | + } |
4856 | + return split_env(val).second == value; |
4857 | + } |
4858 | }; |
4859 | |
4860 | #define TASK_STATE(task) \ |
4861 | @@ -372,1283 +197,823 @@ |
4862 | [&task] { return dbus_test_task_get_state(DBUS_TEST_TASK(task)); } \ |
4863 | } |
4864 | |
4865 | +/* Snapd mock data */ |
4866 | +static std::pair<std::string, std::string> interfaces{ |
4867 | + "GET /v2/interfaces HTTP/1.1\r\nHost: snapd\r\nAccept: */*\r\n\r\n", |
4868 | + SnapdMock::httpJsonResponse(SnapdMock::snapdOkay(SnapdMock::interfacesJson( |
4869 | + {{"unity8", "unity8-package", {"foo", "single", "xmir", "noxmir"}}, {"mir", "unity8-package", {"foo"}}})))}; |
4870 | +static std::pair<std::string, std::string> u8Package{ |
4871 | + "GET /v2/snaps/unity8-package HTTP/1.1\r\nHost: snapd\r\nAccept: */*\r\n\r\n", |
4872 | + SnapdMock::httpJsonResponse(SnapdMock::snapdOkay(SnapdMock::packageJson( |
4873 | + "unity8-package", "active", "app", "1.2.3.4", "x123", {"foo", "single", "xmir", "noxmir"})))}; |
4874 | + |
4875 | TEST_F(LibUAL, StartApplication) |
4876 | { |
4877 | - DbusTestDbusMockObject * obj = dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL); |
4878 | - |
4879 | - /* Basic make sure we can send the event */ |
4880 | - ASSERT_TRUE(ubuntu_app_launch_start_application("com.test.multiple_first_1.2.3", NULL)); |
4881 | - EXPECT_EQ(1, dbus_test_dbus_mock_object_check_method_call(mock, obj, "Start", NULL, NULL)); |
4882 | - |
4883 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL)); |
4884 | - |
4885 | - /* Now look at the details of the call */ |
4886 | - ASSERT_TRUE(ubuntu_app_launch_start_application("com.test.multiple_first_1.2.3", NULL)); |
4887 | - |
4888 | - guint len = 0; |
4889 | - const DbusTestDbusMockCall * calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "Start", &len, NULL); |
4890 | - EXPECT_NE(nullptr, calls); |
4891 | - EXPECT_EQ(1u, len); |
4892 | - |
4893 | - EXPECT_STREQ("Start", calls->name); |
4894 | - EXPECT_EQ(2u, g_variant_n_children(calls->params)); |
4895 | - |
4896 | - GVariant * block = g_variant_get_child_value(calls->params, 1); |
4897 | - EXPECT_TRUE(g_variant_get_boolean(block)); |
4898 | - g_variant_unref(block); |
4899 | - |
4900 | - GVariant * env = g_variant_get_child_value(calls->params, 0); |
4901 | - EXPECT_TRUE(check_env(env, "APP_ID", "com.test.multiple_first_1.2.3")); |
4902 | - g_variant_unref(env); |
4903 | - |
4904 | - ASSERT_TRUE(dbus_test_dbus_mock_object_clear_method_calls(mock, obj, NULL)); |
4905 | - |
4906 | - /* Let's pass some URLs */ |
4907 | - const gchar * urls[] = { |
4908 | - "http://ubuntu.com/", |
4909 | - "https://ubuntu.com/", |
4910 | - "file:///home/phablet/test.txt", |
4911 | - NULL |
4912 | - }; |
4913 | - ASSERT_TRUE(ubuntu_app_launch_start_application("com.test.multiple_first_1.2.3", urls)); |
4914 | - |
4915 | - len = 0; |
4916 | - calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "Start", &len, NULL); |
4917 | - EXPECT_NE(nullptr, calls); |
4918 | - EXPECT_EQ(1u, len); |
4919 | - |
4920 | - env = g_variant_get_child_value(calls->params, 0); |
4921 | - EXPECT_TRUE(check_env(env, "APP_ID", "com.test.multiple_first_1.2.3")); |
4922 | - EXPECT_TRUE(check_env(env, "APP_URIS", "'http://ubuntu.com/' 'https://ubuntu.com/' 'file:///home/phablet/test.txt'")); |
4923 | - g_variant_unref(env); |
4924 | - |
4925 | - return; |
4926 | + /* Basic make sure we can send the event */ |
4927 | + ASSERT_TRUE(ubuntu_app_launch_start_application("single", NULL)); |
4928 | + |
4929 | + std::list<SystemdMock::TransientUnit> calls; |
4930 | + ASSERT_EVENTUALLY_FUNC_LT(0u, std::function<unsigned int(void)>([&]() { |
4931 | + calls = systemd->unitCalls(); |
4932 | + return calls.size(); |
4933 | + })); |
4934 | + EXPECT_EQ(SystemdMock::instanceName({"application-legacy", "single", {}, 0, {}}), calls.begin()->name); |
4935 | + |
4936 | + systemd->managerClear(); |
4937 | + |
4938 | + /* Let's pass some URLs */ |
4939 | + const gchar *urls[] = {"http://ubuntu.com/", "https://ubuntu.com/", "file:///home/phablet/test.txt", NULL}; |
4940 | + ASSERT_TRUE(ubuntu_app_launch_start_application("foo", urls)); |
4941 | + |
4942 | + ASSERT_EVENTUALLY_FUNC_LT(0u, std::function<unsigned int(void)>([&]() { |
4943 | + calls = systemd->unitCalls(); |
4944 | + return calls.size(); |
4945 | + })); |
4946 | + |
4947 | + EXPECT_EQ("file:///home/phablet/test.txt", *(calls.begin()->execline.rbegin())); |
4948 | + EXPECT_EQ("https://ubuntu.com/", *(++calls.begin()->execline.rbegin())); |
4949 | + EXPECT_EQ("http://ubuntu.com/", *(++(++calls.begin()->execline.rbegin()))); |
4950 | + |
4951 | + return; |
4952 | } |
4953 | |
4954 | TEST_F(LibUAL, StartApplicationTest) |
4955 | { |
4956 | - DbusTestDbusMockObject * obj = dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL); |
4957 | - |
4958 | - ASSERT_TRUE(ubuntu_app_launch_start_application_test("com.test.multiple_first_1.2.3", NULL)); |
4959 | - |
4960 | - guint len = 0; |
4961 | - const DbusTestDbusMockCall * calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "Start", &len, NULL); |
4962 | - EXPECT_NE(nullptr, calls); |
4963 | - EXPECT_EQ(1u, len); |
4964 | - |
4965 | - EXPECT_STREQ("Start", calls->name); |
4966 | - EXPECT_EQ(2u, g_variant_n_children(calls->params)); |
4967 | - |
4968 | - GVariant * block = g_variant_get_child_value(calls->params, 1); |
4969 | - EXPECT_TRUE(g_variant_get_boolean(block)); |
4970 | - g_variant_unref(block); |
4971 | - |
4972 | - GVariant * env = g_variant_get_child_value(calls->params, 0); |
4973 | - EXPECT_TRUE(check_env(env, "APP_ID", "com.test.multiple_first_1.2.3")); |
4974 | - EXPECT_TRUE(check_env(env, "QT_LOAD_TESTABILITY", "1")); |
4975 | - g_variant_unref(env); |
4976 | + ASSERT_TRUE(ubuntu_app_launch_start_application_test("foo", nullptr)); |
4977 | + |
4978 | + std::list<SystemdMock::TransientUnit> calls; |
4979 | + ASSERT_EVENTUALLY_FUNC_LT(0u, std::function<unsigned int(void)>([&]() { |
4980 | + calls = systemd->unitCalls(); |
4981 | + return calls.size(); |
4982 | + })); |
4983 | + |
4984 | + EXPECT_TRUE(check_env(calls.begin()->environment, "QT_LOAD_TESTABILITY", "1")); |
4985 | } |
4986 | |
4987 | TEST_F(LibUAL, StopApplication) |
4988 | { |
4989 | - DbusTestDbusMockObject * obj = dbus_test_dbus_mock_get_object(mock, "/com/test/application_click", "com.ubuntu.Upstart0_6.Job", NULL); |
4990 | - |
4991 | - ASSERT_TRUE(ubuntu_app_launch_stop_application("com.test.good_application_1.2.3")); |
4992 | - |
4993 | - ASSERT_EQ(dbus_test_dbus_mock_object_check_method_call(mock, obj, "Stop", NULL, NULL), 1); |
4994 | - |
4995 | + ASSERT_TRUE(ubuntu_app_launch_stop_application("single")); |
4996 | + |
4997 | + std::list<std::string> calls; |
4998 | + ASSERT_EVENTUALLY_FUNC_LT(0u, std::function<unsigned int(void)>([&]() { |
4999 | + calls = systemd->stopCalls(); |
5000 | + return calls.size(); |
FAILED: Continuous integration, rev:324 /jenkins. canonical. com/unity- api-1/job/ lp-ubuntu- app-launch- ci/232/ /jenkins. canonical. com/unity- api-1/job/ build/1704/ console /jenkins. canonical. com/unity- api-1/job/ build-0- fetch/1711 /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= xenial+ overlay/ 1487/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=amd64, release= zesty/1487/ console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= xenial+ overlay/ 1487/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=armhf, release= zesty/1487/ console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= xenial+ overlay/ 1487/console /jenkins. canonical. com/unity- api-1/job/ build-2- binpkg/ arch=i386, release= zesty/1487/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/unity- api-1/job/ lp-ubuntu- app-launch- ci/232/ rebuild
https:/