Merge lp:~ted/url-dispatcher/devel into lp:~fboucault/url-dispatcher/crossbuild_fixes

Proposed by Ted Gould
Status: Superseded
Proposed branch: lp:~ted/url-dispatcher/devel
Merge into: lp:~fboucault/url-dispatcher/crossbuild_fixes
Diff against target: 2134 lines (+1222/-123)
49 files modified
CMakeLists.txt (+12/-4)
data/CMakeLists.txt (+10/-0)
data/bad-url.qml (+42/-0)
data/url-dispatcher-update-user.conf.in (+1/-1)
data/url-dispatcher.conf.in (+4/-0)
debian/apparmor/url-dispatcher-bad-url-helper (+15/-0)
debian/changelog (+23/-0)
debian/control (+19/-0)
debian/rules (+1/-0)
debian/url-dispatcher-tools-gui.install (+2/-0)
debian/url-dispatcher.install (+3/-0)
gui/CMakeLists.txt (+13/-0)
gui/url-dispatcher-gui.desktop.in (+6/-0)
gui/url-dispatcher-gui.qml (+59/-0)
gui/url-dispatcher-gui.svg (+129/-0)
po/CMakeLists.txt (+39/-0)
po/POTFILES.in (+1/-0)
po/genpotfiles.sh (+6/-0)
service/CMakeLists.txt (+11/-13)
service/bad-url/CMakeLists.txt (+14/-0)
service/bad-url/exec-tool.c (+42/-0)
service/dispatcher.c (+141/-6)
service/dispatcher.h (+2/-1)
service/overlay-tracker-iface.h (+1/-0)
service/overlay-tracker-mir.cpp (+69/-39)
service/overlay-tracker-mir.h (+22/-8)
service/overlay-tracker.cpp (+9/-0)
service/overlay-tracker.h (+1/-0)
service/scope-checker-facade.h (+27/-0)
service/scope-checker.cpp (+114/-0)
service/scope-checker.h (+29/-0)
service/service.c (+9/-1)
service/url-overlay/CMakeLists.txt (+14/-0)
tests/CMakeLists.txt (+3/-0)
tests/app-id-test.cc (+27/-29)
tests/apparmor-mock.c (+36/-0)
tests/apparmor-mock.h (+20/-0)
tests/click-data/manifests/com.test.good.manifest (+1/-1)
tests/click-data/manifests/com.test.multiple.manifest (+3/-3)
tests/dispatcher-test.cc (+84/-1)
tests/overlay-tracker-mock.h (+6/-0)
tests/overlay-tracker-test.cpp (+41/-12)
tests/scope-mock.h (+95/-0)
tests/service-test.cc (+8/-3)
tests/test-config.h.in (+1/-1)
tests/ual-link-farm/com.test.good_app1_1.2.3.desktop (+1/-0)
tests/ual-link-farm/com.test.multiple_app-first_1.2.3.desktop (+1/-0)
tests/xdg-cache/libertine-container/container-id/rootfs/usr/share/applications/org.canonical.app1.desktop (+4/-0)
tests/xdg-data/applications/foo-bar.desktop (+1/-0)
To merge this branch: bzr merge lp:~ted/url-dispatcher/devel
Reviewer Review Type Date Requested Status
Florian Boucault Pending
Review via email: mp+306285@code.launchpad.net

This proposal has been superseded by a proposal from 2016-09-20.

Commit message

Pull all the branches together for merge conflicts

Description of the change

The merge conflicts were too difficult to make easy sense of, so pulled everything into a single branch that we can then land. This is the combination of a whole host of branches.

To post a comment you must log in.
lp:~ted/url-dispatcher/devel updated
105. By Ted Gould

Merge issues from trunk

106. By Ted Gould

Forgot the container config

107. By Ted Gould

Fixes from review

108. By Ted Gould

Be more specific so that the packages don't conflict

Unmerged revisions

108. By Ted Gould

Be more specific so that the packages don't conflict

107. By Ted Gould

Fixes from review

106. By Ted Gould

Forgot the container config

105. By Ted Gould

Merge issues from trunk

104. By Ted Gould

Updating changelog to have all the branches in it

103. By Ted Gould

Fixing the environment for the appid test

102. By Ted Gould

Bad URL prompt

101. By Ted Gould

Merge lp:~ted/url-dispatcher/gui-tool/

100. By Ted Gould

Merge lp:~ted/url-dispatcher/ual-snappy-autopkgtest/

99. By Ted Gould

Merge lp:~ted/url-dispatcher/lp1608009-no-message/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-06-11 21:38:13 +0000
3+++ CMakeLists.txt 2016-09-20 21:26:50 +0000
4@@ -3,7 +3,7 @@
5
6 string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) # Build types should always be lowercase but sometimes they are not.
7
8-if (${cmake_build_type_lower} STREQUAL debug)
9+if ("${cmake_build_type_lower}" STREQUAL "debug")
10 option (werror "Treat warnings as errors." FALSE)
11 else()
12 option (werror "Treat warnings as errors." TRUE)
13@@ -30,7 +30,7 @@
14 include(UseConstantBuilder)
15
16 # Workaround for libexecdir on debian
17-if (EXISTS "/etc/debian_version")
18+if (EXISTS "/etc/debian_version")
19 set(CMAKE_INSTALL_LIBEXECDIR ${CMAKE_INSTALL_LIBDIR})
20 set(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}")
21 endif()
22@@ -42,7 +42,7 @@
23 # Since gdbus-codegen does not produce warning-free code
24 # and we use -Werror, only enable these warnings for debug
25 # builds. Drop this once the issue has been fixed and landed.
26-if (${cmake_build_type_lower} STREQUAL debug)
27+if ("${cmake_build_type_lower}" STREQUAL debug)
28 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic")# -Wextra")
29 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic -Wextra")
30 endif()
31@@ -50,7 +50,7 @@
32 if (${werror})
33 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
34 set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
35-endif()
36+endif()
37
38 pkg_check_modules(UBUNTU_APP_LAUNCH REQUIRED ubuntu-app-launch-2>=0.5)
39 include_directories(${UBUNTU_APP_LAUNCH_INCLUDE_DIRS})
40@@ -79,6 +79,12 @@
41 pkg_check_modules(CLICK REQUIRED click-0.4)
42 include_directories(${CLICK_INCLUDE_DIRS})
43
44+pkg_check_modules(SCOPES REQUIRED libunity-scopes)
45+include_directories(${SCOPES_INCLUDE_DIRS})
46+
47+pkg_check_modules(APPARMOR REQUIRED libapparmor)
48+include_directories(${APPARMOR_INCLUDE_DIRS})
49+
50 if(${LOCAL_INSTALL})
51 set(DBUSSERVICEDIR "${CMAKE_INSTALL_DATADIR}/dbus-1/services/")
52 else()
53@@ -103,6 +109,7 @@
54 add_subdirectory(service)
55 add_subdirectory(liburl-dispatcher)
56 add_subdirectory(tools)
57+add_subdirectory(gui)
58
59 # testing & coverage
60 if (${enable_tests})
61@@ -116,3 +123,4 @@
62 add_subdirectory(tests)
63 endif ()
64
65+add_subdirectory(po)
66
67=== modified file 'data/CMakeLists.txt'
68--- data/CMakeLists.txt 2015-11-06 22:59:11 +0000
69+++ data/CMakeLists.txt 2016-09-20 21:26:50 +0000
70@@ -102,3 +102,13 @@
71 @ONLY
72 )
73
74+###########################
75+# QML
76+###########################
77+
78+install(
79+FILES
80+bad-url.qml
81+DESTINATION ${datadir}/url-dispatcher
82+)
83+
84
85=== added file 'data/bad-url.qml'
86--- data/bad-url.qml 1970-01-01 00:00:00 +0000
87+++ data/bad-url.qml 2016-09-20 21:26:50 +0000
88@@ -0,0 +1,42 @@
89+/*
90+ * Copyright © 2015 Canonical Ltd.
91+ *
92+ * This program is free software; you can redistribute it and/or modify
93+ * it under the terms of the GNU General Public License as published by
94+ * the Free Software Foundation; version 3.
95+ *
96+ * This program is distributed in the hope that it will be useful,
97+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
98+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99+ * GNU General Public License for more details.
100+ *
101+ * You should have received a copy of the GNU General Public License
102+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
103+ */
104+
105+import QtQuick 2.0
106+import Ubuntu.Components 1.0
107+import Ubuntu.Components.Popups 1.0
108+
109+MainView {
110+ applicationName: "com.canonical.url-dispatcher.bad-url-prompt"
111+ automaticOrientation: true
112+ backgroundColor: "transparent"
113+ anchors.fill: parent
114+
115+ Component {
116+ id: dialog
117+ Dialog {
118+ title: i18n.tr("Unrecognized Address")
119+ text: i18n.tr("Ubuntu can't open addresses of type “%1”.").arg(Qt.application.arguments[2].split(':')[0])
120+
121+ Button {
122+ text: i18n.tr("OK")
123+ color: UbuntuColors.orange
124+ onClicked: Qt.quit()
125+ }
126+ }
127+ }
128+
129+ Component.onCompleted: PopupUtils.open(dialog)
130+}
131
132=== modified file 'data/url-dispatcher-update-user.conf.in'
133--- data/url-dispatcher-update-user.conf.in 2015-09-04 19:53:45 +0000
134+++ data/url-dispatcher-update-user.conf.in 2016-09-20 21:26:50 +0000
135@@ -13,4 +13,4 @@
136 fi
137 end script
138
139-exec @pkglibexecdir@/update-directory "~/.config/url-dispatcher/urls/*.url-dispatcher"
140+exec @pkglibexecdir@/update-directory "${HOME}/.config/url-dispatcher/urls/"
141
142=== modified file 'data/url-dispatcher.conf.in'
143--- data/url-dispatcher.conf.in 2015-11-06 23:05:12 +0000
144+++ data/url-dispatcher.conf.in 2016-09-20 21:26:50 +0000
145@@ -7,6 +7,7 @@
146 respawn
147
148 emits application-start
149+emits untrusted-helper-type-end
150
151 script
152 @pkglibexecdir@/url-dispatcher
153@@ -18,3 +19,6 @@
154 fi
155 end script
156
157+post-stop script
158+ initctl emit untrusted-helper-type-end HELPER_TYPE=url-overlay
159+end script
160
161=== added directory 'debian/apparmor'
162=== added file 'debian/apparmor/url-dispatcher-bad-url-helper'
163--- debian/apparmor/url-dispatcher-bad-url-helper 1970-01-01 00:00:00 +0000
164+++ debian/apparmor/url-dispatcher-bad-url-helper 2016-09-20 21:26:50 +0000
165@@ -0,0 +1,15 @@
166+# vim:syntax=apparmor
167+#include <tunables/global>
168+
169+# Mostly unconfined. Don't allow capability or any mount rules. Also ensure that
170+# exec inherits from this profile
171+profile url-dispatcher-bad-url-helper (attach_disconnected) {
172+ network,
173+ / rwkl,
174+ /** rwlkm,
175+ /** pix,
176+ dbus,
177+ signal,
178+ ptrace,
179+ unix,
180+}
181
182=== modified file 'debian/changelog'
183--- debian/changelog 2015-11-10 14:37:07 +0000
184+++ debian/changelog 2016-09-20 21:26:50 +0000
185@@ -1,3 +1,26 @@
186+url-dispatcher (0.1+16.04.20151110-0ubuntu2) UNRELEASED; urgency=medium
187+
188+ [ Florian Boucault ]
189+ * Crossbuilding Fixes
190+
191+ [ Larry Price ]
192+ * App ID should allow package names with dots. (LP: #1591342) (LP: #1606498)
193+
194+ [ Ted Gould ]
195+ * Check versions of appid:// urls to reduce the number of invalid appids
196+ we send to UAL (LP: #1352656)
197+ * Scope testing for the scope:// URL and overlays that should be over
198+ the dash
199+ * Protect the dash from getting NULL urls (LP: #1476257)
200+ * Make sure URL Overlays are shutdown on exit
201+ * Remove the wildcard that is confusing the update script (LP: #1461496)
202+ * Not using a message that isn't set properly (LP: #1608009)
203+ * Fixing tests to adjust for UAL changes
204+ * Add a small GUI helper tool for testing
205+ * Show error dialog over apps that use Bad URLs (LP: #1370008)
206+
207+ -- Ted Gould <ted@ubuntu.com> Tue, 20 Sep 2016 16:17:26 -0500
208+
209 url-dispatcher (0.1+16.04.20151110-0ubuntu1) xenial; urgency=medium
210
211 [ CI Train Bot ]
212
213=== modified file 'debian/control'
214--- debian/control 2016-07-19 21:01:20 +0000
215+++ debian/control 2016-09-20 21:26:50 +0000
216@@ -7,8 +7,10 @@
217 dbus-test-runner,
218 debhelper (>= 9),
219 dh-autoreconf,
220+ dh-apparmor,
221 gtester2xunit,
222 intltool,
223+ libapparmor-dev,
224 libclick-0.4-dev,
225 libdbus-1-dev,
226 libdbustest1-dev (>= 14.04.0),
227@@ -17,6 +19,7 @@
228 libgtest-dev,
229 libsqlite3-dev,
230 libubuntu-app-launch2-dev (>= 0.5),
231+ libunity-scopes-dev,
232 python3:any,
233 python3-dbusmock <!cross>,
234 python3-fixtures <!cross>,
235@@ -38,6 +41,9 @@
236 Pre-Depends: ${misc:Pre-Depends},
237 Depends: ${misc:Depends},
238 ${shlibs:Depends},
239+# For the bad URL dialog
240+ qtchooser,
241+ qtdeclarative5-ubuntu-ui-toolkit-plugin,
242 Description: service to allow sending of URLs and get handlers started
243 Allows applications to request a URL to be opened and handled by another
244 process without seeing the list of other applications on the system or
245@@ -57,6 +63,19 @@
246 .
247 This package provides tools for working with the URL Dispatcher.
248
249+Package: url-dispatcher-tools-gui
250+Architecture: any
251+Depends: url-dispatcher (= ${binary:Version}),
252+ ${misc:Depends},
253+ ${shlibs:Depends},
254+ qtchooser,
255+Description: GUI tools for working with the URL Dispatcher.
256+ Allows applications to request a URL to be opened and handled by another
257+ process without seeing the list of other applications on the system or
258+ starting them inside its own Application Confinement.
259+ .
260+ This package provides GUI tools for working with the URL Dispatcher.
261+
262 Package: liburl-dispatcher1
263 Section: libs
264 Architecture: any
265
266=== modified file 'debian/rules'
267--- debian/rules 2016-07-19 21:01:20 +0000
268+++ debian/rules 2016-09-20 21:26:50 +0000
269@@ -15,6 +15,7 @@
270 install -m 644 debian/source_url-dispatcher.py debian/url-dispatcher/usr/share/apport/package-hooks/
271 mkdir -p debian/url-dispatcher/etc/apport/crashdb.conf.d/
272 install -m 644 debian/url-dispatcher-crashdb.conf debian/url-dispatcher/etc/apport/crashdb.conf.d/
273+ dh_apparmor --profile-name=url-dispatcher-bad-url-helper -p url-dispatcher
274 dh_install --fail-missing
275
276 override_dh_click:
277
278=== added file 'debian/url-dispatcher-tools-gui.install'
279--- debian/url-dispatcher-tools-gui.install 1970-01-01 00:00:00 +0000
280+++ debian/url-dispatcher-tools-gui.install 2016-09-20 21:26:50 +0000
281@@ -0,0 +1,2 @@
282+/usr/share/applications/
283+/usr/share/url-dispatcher/gui/
284
285=== modified file 'debian/url-dispatcher.install'
286--- debian/url-dispatcher.install 2015-06-12 16:00:37 +0000
287+++ debian/url-dispatcher.install 2016-09-20 21:26:50 +0000
288@@ -1,5 +1,8 @@
289 usr/lib/*/url-dispatcher
290 usr/lib/*/ubuntu-app-launch/url-overlay/exec-tool
291+usr/lib/*/ubuntu-app-launch/bad-url/exec-tool
292 usr/share/dbus-1
293 usr/share/upstart/sessions
294+usr/share/url-dispatcher
295 usr/bin/url-dispatcher-dump
296+debian/apparmor/url-dispatcher-bad-url-helper etc/apparmor.d
297
298=== added directory 'gui'
299=== added file 'gui/CMakeLists.txt'
300--- gui/CMakeLists.txt 1970-01-01 00:00:00 +0000
301+++ gui/CMakeLists.txt 2016-09-20 21:26:50 +0000
302@@ -0,0 +1,13 @@
303+
304+install(FILES
305+ url-dispatcher-gui.qml
306+ url-dispatcher-gui.svg
307+ DESTINATION "${CMAKE_INSTALL_DATADIR}/url-dispatcher/gui/")
308+install(FILES
309+ ${CMAKE_CURRENT_BINARY_DIR}/url-dispatcher-gui.desktop
310+ DESTINATION "${CMAKE_INSTALL_DATADIR}/applications/")
311+
312+configure_file(
313+ "url-dispatcher-gui.desktop.in"
314+ "url-dispatcher-gui.desktop"
315+ @ONLY)
316
317=== added file 'gui/url-dispatcher-gui.desktop.in'
318--- gui/url-dispatcher-gui.desktop.in 1970-01-01 00:00:00 +0000
319+++ gui/url-dispatcher-gui.desktop.in 2016-09-20 21:26:50 +0000
320@@ -0,0 +1,6 @@
321+[Desktop Entry]
322+Name=URL Dispatcher GUI
323+Icon=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_DATADIR@/url-dispatcher/gui/url-dispatcher-gui.svg
324+Type=Application
325+Exec=qmlscene @CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_DATADIR@/url-dispatcher/gui/url-dispatcher-gui.qml
326+X-Ubuntu-Touch=true
327
328=== added file 'gui/url-dispatcher-gui.qml'
329--- gui/url-dispatcher-gui.qml 1970-01-01 00:00:00 +0000
330+++ gui/url-dispatcher-gui.qml 2016-09-20 21:26:50 +0000
331@@ -0,0 +1,59 @@
332+import QtQuick 2.4
333+import Ubuntu.Components 1.3
334+import Ubuntu.Components.ListItems 1.3
335+
336+MainView {
337+ applicationName: "url-dispatcher-gui"
338+
339+ Page {
340+ header: PageHeader {
341+ title: "URL Dispatcher GUI"
342+ flickable: flickme
343+ }
344+
345+ Flickable {
346+ id: flickme
347+ anchors.fill: parent
348+
349+ Column {
350+ anchors.fill: parent
351+
352+ ListItem {
353+ contentItem.anchors {
354+ leftMargin: units.gu(2)
355+ rightMargin: units.gu(2)
356+ topMargin: units.gu(1)
357+ bottomMargin: units.gu(1)
358+ }
359+
360+ TextField {
361+ id: textbox
362+ anchors.fill: parent
363+ placeholderText: "URL (e.g. 'http://ubuntu.com')"
364+ }
365+ }
366+
367+ ListItem {
368+ contentItem.anchors {
369+ leftMargin: units.gu(2)
370+ rightMargin: units.gu(2)
371+ topMargin: units.gu(1)
372+ bottomMargin: units.gu(1)
373+ }
374+
375+ Button {
376+ anchors.fill: parent
377+ text: "Send URL"
378+ onClicked: {
379+ console.log("Sending URL: " + textbox.text)
380+ Qt.openUrlExternally(textbox.text)
381+ }
382+ }
383+ }
384+ }
385+ }
386+
387+ }
388+
389+
390+}
391
392=== added file 'gui/url-dispatcher-gui.svg'
393--- gui/url-dispatcher-gui.svg 1970-01-01 00:00:00 +0000
394+++ gui/url-dispatcher-gui.svg 2016-09-20 21:26:50 +0000
395@@ -0,0 +1,129 @@
396+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
397+<!-- Created with Inkscape (http://www.inkscape.org/) -->
398+
399+<svg
400+ xmlns:dc="http://purl.org/dc/elements/1.1/"
401+ xmlns:cc="http://creativecommons.org/ns#"
402+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
403+ xmlns:svg="http://www.w3.org/2000/svg"
404+ xmlns="http://www.w3.org/2000/svg"
405+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
406+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
407+ width="256"
408+ height="256"
409+ viewBox="0 0 67.733332 67.733335"
410+ version="1.1"
411+ id="svg8"
412+ inkscape:version="0.92pre1 15068"
413+ sodipodi:docname="url-dispatcher-gui.svg">
414+ <defs
415+ id="defs2" />
416+ <sodipodi:namedview
417+ id="base"
418+ pagecolor="#ffffff"
419+ bordercolor="#666666"
420+ borderopacity="1.0"
421+ inkscape:pageopacity="1"
422+ inkscape:pageshadow="2"
423+ inkscape:zoom="3.375"
424+ inkscape:cx="128"
425+ inkscape:cy="128.88889"
426+ inkscape:document-units="mm"
427+ inkscape:current-layer="g3484"
428+ showgrid="false"
429+ units="px"
430+ inkscape:showpageshadow="false"
431+ inkscape:pagecheckerboard="false"
432+ inkscape:window-width="1920"
433+ inkscape:window-height="1050"
434+ inkscape:window-x="0"
435+ inkscape:window-y="30"
436+ inkscape:window-maximized="1" />
437+ <metadata
438+ id="metadata5">
439+ <rdf:RDF>
440+ <cc:Work
441+ rdf:about="">
442+ <dc:format>image/svg+xml</dc:format>
443+ <dc:type
444+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
445+ <dc:title></dc:title>
446+ </cc:Work>
447+ </rdf:RDF>
448+ </metadata>
449+ <g
450+ inkscape:label="Layer 1"
451+ inkscape:groupmode="layer"
452+ id="layer1"
453+ transform="translate(0,-229.26665)">
454+ <g
455+ id="g3484"
456+ transform="translate(0,-2.732619)">
457+ <path
458+ inkscape:connector-curvature="0"
459+ id="path3486"
460+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:17.4939785px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.69975913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
461+ d="m 16.89882,270.19082 q -1.903345,0 -3.302863,-0.5878 -1.399518,-0.58779 -2.29521,-1.59545 -0.895692,-1.03564 -1.3435374,-2.43516 -0.4198555,-1.39952 -0.4198555,-3.02296 V 250.37364 H 12.25242 v 11.86792 q 0,2.911 1.287556,4.22654 1.287557,1.31555 3.358844,1.31555 1.035644,0 1.875355,-0.30789 0.867701,-0.33589 1.483489,-1.00766 0.615788,-0.67177 0.951673,-1.70741 0.335884,-1.06363 0.335884,-2.51913 v -11.86792 h 2.715066 v 12.17581 q 0,1.62344 -0.447846,3.02296 -0.419856,1.39952 -1.343538,2.43516 -0.895692,1.00766 -2.29521,1.59545 -1.371528,0.5878 -3.274873,0.5878 z" />
462+ <path
463+ inkscape:connector-curvature="0"
464+ id="path3488"
465+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:17.4939785px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.69975913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
466+ d="m 38.409416,261.65376 q 0.447846,0.55981 1.119614,1.48349 0.69976,0.89569 1.427509,2.01531 0.72775,1.09162 1.427509,2.29521 0.727749,1.20358 1.231576,2.3232 h -2.966979 q -0.559807,-1.06364 -1.231576,-2.15526 -0.643778,-1.09163 -1.315547,-2.07129 -0.671769,-1.00765 -1.343538,-1.87535 -0.643778,-0.86771 -1.175595,-1.51148 -0.363875,0.028 -0.75574,0.028 -0.363875,0 -0.75574,0 h -2.435162 v 7.58539 h -2.715065 v -19.11742 q 1.147605,-0.27991 2.547123,-0.36388 1.427509,-0.11196 2.603104,-0.11196 4.086593,0 6.213861,1.53947 2.155258,1.53947 2.155258,4.59042 0,1.93133 -1.035643,3.30286 -1.007653,1.37153 -2.994969,2.0433 z m -4.114584,-9.09687 q -1.735403,0 -2.659085,0.084 v 7.30549 h 1.931335 q 1.399519,0 2.519133,-0.13995 1.119615,-0.13996 1.875355,-0.53182 0.78373,-0.39187 1.203586,-1.09163 0.419855,-0.72775 0.419855,-1.90334 0,-1.09163 -0.419855,-1.81937 -0.419856,-0.72775 -1.147605,-1.14761 -0.69976,-0.41986 -1.679422,-0.5878 -0.951673,-0.16794 -2.043297,-0.16794 z" />
467+ <path
468+ inkscape:connector-curvature="0"
469+ id="path3490"
470+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:17.4939785px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.69975913px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
471+ d="m 58.19598,267.41977 v 2.3512 H 46.523997 v -19.39733 h 2.715066 v 17.04613 z" />
472+ <path
473+ inkscape:connector-curvature="0"
474+ id="path3493"
475+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
476+ d="m 16.002471,276.35782 q 0,0.87908 -0.273492,1.5335 -0.273492,0.64466 -0.771638,1.07444 -0.498145,0.42 -1.191643,0.63489 -0.693497,0.20512 -1.52374,0.20512 -0.410238,0 -0.908384,-0.0391 -0.488379,-0.0293 -0.888849,-0.12698 v -6.56381 q 0.40047,-0.0977 0.888849,-0.12698 0.498146,-0.0391 0.908384,-0.0391 0.830243,0 1.52374,0.21489 0.693498,0.20512 1.191643,0.63489 0.498146,0.42001 0.771638,1.07444 0.273492,0.64465 0.273492,1.52374 z m -3.682373,2.6177 q 1.347925,0 2.012119,-0.68373 0.664195,-0.69349 0.664195,-1.93397 0,-1.24049 -0.664195,-1.92421 -0.664194,-0.6935 -2.012119,-0.6935 -0.40047,0 -0.625124,0.01 -0.214887,0.01 -0.302795,0.0195 v 5.17681 q 0.08791,0.01 0.302795,0.0195 0.224654,0.01 0.625124,0.01 z" />
477+ <path
478+ inkscape:connector-curvature="0"
479+ id="path3495"
480+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
481+ d="m 18.257711,279.74716 h -0.908384 v -5.07913 h 0.908384 z m -0.459076,-5.99728 q -0.244189,0 -0.420005,-0.15629 -0.166049,-0.16604 -0.166049,-0.43954 0,-0.27349 0.166049,-0.42977 0.175816,-0.16605 0.420005,-0.16605 0.244189,0 0.410238,0.16605 0.175816,0.15628 0.175816,0.42977 0,0.2735 -0.175816,0.43954 -0.166049,0.15629 -0.410238,0.15629 z" />
482+ <path
483+ inkscape:connector-curvature="0"
484+ id="path3497"
485+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
486+ d="m 21.011249,279.09273 q 0.556751,0 0.820476,-0.14651 0.273492,-0.14651 0.273492,-0.46884 0,-0.3321 -0.263725,-0.52745 -0.263724,-0.19535 -0.869313,-0.43954 -0.293027,-0.11721 -0.566519,-0.23442 -0.263725,-0.12698 -0.459076,-0.29303 -0.195351,-0.16605 -0.312562,-0.40047 -0.117211,-0.23442 -0.117211,-0.57629 0,-0.67396 0.498146,-1.06466 0.498146,-0.40047 1.357692,-0.40047 0.214886,0 0.429773,0.0293 0.214886,0.0195 0.40047,0.0586 0.185584,0.0293 0.32233,0.0684 0.146514,0.0391 0.224654,0.0684 l -0.166049,0.78141 q -0.146513,-0.0781 -0.459075,-0.15628 -0.312562,-0.0879 -0.752103,-0.0879 -0.380935,0 -0.664195,0.15628 -0.283259,0.14651 -0.283259,0.46884 0,0.16605 0.05861,0.29303 0.06837,0.12698 0.195352,0.23442 0.136746,0.0977 0.332097,0.18559 0.195351,0.0879 0.468843,0.18558 0.3614,0.13675 0.64466,0.27349 0.283259,0.12698 0.478611,0.3028 0.205118,0.17581 0.312562,0.42977 0.107443,0.24419 0.107443,0.60559 0,0.70326 -0.527449,1.06466 -0.517681,0.3614 -1.48467,0.3614 -0.673962,0 -1.054897,-0.11721 -0.380935,-0.10744 -0.517681,-0.16605 l 0.166048,-0.7814 q 0.156281,0.0586 0.498146,0.17581 0.341865,0.11721 0.908384,0.11721 z" />
487+ <path
488+ inkscape:connector-curvature="0"
489+ id="path3499"
490+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
491+ d="m 27.705085,277.21736 q 0,-0.88885 -0.43954,-1.36746 -0.439541,-0.47861 -1.172109,-0.47861 -0.410237,0 -0.644659,0.0293 -0.224654,0.0293 -0.3614,0.0684 v 3.20376 q 0.166049,0.13675 0.478611,0.26372 0.312562,0.12698 0.68373,0.12698 0.390702,0 0.664194,-0.13674 0.28326,-0.14652 0.459076,-0.39071 0.175816,-0.25395 0.253957,-0.58605 0.07814,-0.34187 0.07814,-0.73257 z m 0.947454,0 q 0,0.57629 -0.156281,1.06467 -0.146513,0.48838 -0.43954,0.84001 -0.293027,0.35163 -0.7228,0.54698 -0.420006,0.19535 -0.96699,0.19535 -0.43954,0 -0.781405,-0.11721 -0.332097,-0.11721 -0.498146,-0.22465 v 2.03165 h -0.908384 v -6.72985 q 0.32233,-0.0781 0.800941,-0.16605 0.488378,-0.0977 1.12327,-0.0977 0.586054,0 1.054897,0.18559 0.468844,0.18558 0.800941,0.52745 0.332097,0.34186 0.507913,0.84001 0.185584,0.48838 0.185584,1.10373 z" />
492+ <path
493+ inkscape:connector-curvature="0"
494+ id="path3501"
495+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
496+ d="m 31.659424,279.09273 q 0.32233,0 0.566519,-0.01 0.253957,-0.0195 0.420006,-0.0586 v -1.51397 q -0.09768,-0.0488 -0.32233,-0.0781 -0.214887,-0.0391 -0.527449,-0.0391 -0.205119,0 -0.43954,0.0293 -0.224654,0.0293 -0.420006,0.12698 -0.185584,0.0879 -0.312562,0.25396 -0.126978,0.15628 -0.126978,0.42 0,0.48838 0.312562,0.68373 0.312562,0.18558 0.849778,0.18558 z m -0.07814,-4.55168 q 0.546984,0 0.918151,0.14651 0.380935,0.13675 0.605589,0.40047 0.234422,0.25396 0.332098,0.61536 0.09767,0.35163 0.09767,0.7814 v 3.17446 q -0.117211,0.0195 -0.332097,0.0586 -0.205119,0.0293 -0.468843,0.0586 -0.263725,0.0293 -0.576287,0.0488 -0.302794,0.0293 -0.605589,0.0293 -0.429773,0 -0.791173,-0.0879 -0.3614,-0.0879 -0.625124,-0.27349 -0.263725,-0.19536 -0.410238,-0.50792 -0.146514,-0.31256 -0.146514,-0.7521 0,-0.42001 0.166049,-0.7228 0.175816,-0.3028 0.468843,-0.48838 0.293027,-0.18558 0.68373,-0.27349 0.390703,-0.0879 0.820476,-0.0879 0.136746,0 0.283259,0.0195 0.146514,0.01 0.273492,0.0391 0.136746,0.0195 0.234422,0.0391 0.09768,0.0195 0.136746,0.0293 v -0.25396 q 0,-0.22465 -0.04884,-0.43954 -0.04884,-0.22465 -0.175816,-0.3907 -0.126979,-0.17582 -0.351633,-0.27349 -0.214886,-0.10745 -0.566519,-0.10745 -0.449308,0 -0.791173,0.0684 -0.332097,0.0586 -0.498146,0.12698 l -0.107443,-0.75211 q 0.175816,-0.0781 0.586054,-0.14651 0.410238,-0.0781 0.888849,-0.0781 z" />
497+ <path
498+ inkscape:connector-curvature="0"
499+ id="path3503"
500+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
501+ d="m 35.883744,274.66803 h 1.924211 v 0.76187 h -1.924211 v 2.34421 q 0,0.38094 0.05861,0.6349 0.05861,0.24418 0.175816,0.3907 0.117211,0.13674 0.293027,0.19535 0.175816,0.0586 0.410238,0.0586 0.410238,0 0.654427,-0.0879 0.253957,-0.0977 0.351632,-0.13675 l 0.175817,0.7521 q -0.136746,0.0684 -0.478611,0.16605 -0.341865,0.10745 -0.781406,0.10745 -0.517681,0 -0.859546,-0.12698 -0.332097,-0.13675 -0.537216,-0.40047 -0.205119,-0.26373 -0.293027,-0.64466 -0.07814,-0.39071 -0.07814,-0.89862 v -4.53215 l 0.908383,-0.15628 z" />
502+ <path
503+ inkscape:connector-curvature="0"
504+ id="path3505"
505+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
506+ d="m 41.037815,279.86437 q -0.615356,0 -1.0842,-0.19535 -0.459075,-0.19535 -0.781405,-0.54698 -0.312562,-0.35163 -0.468843,-0.83025 -0.156281,-0.48837 -0.156281,-1.07443 0,-0.58605 0.166048,-1.07443 0.175817,-0.48838 0.488379,-0.84001 0.312562,-0.3614 0.76187,-0.55675 0.459076,-0.20512 1.015827,-0.20512 0.341865,0 0.68373,0.0586 0.341865,0.0586 0.654427,0.18559 l -0.205119,0.77164 q -0.205119,-0.0977 -0.478611,-0.15629 -0.263724,-0.0586 -0.566519,-0.0586 -0.76187,0 -1.172108,0.47861 -0.40047,0.47861 -0.40047,1.39676 0,0.41024 0.08791,0.7521 0.09768,0.34187 0.293027,0.58606 0.205119,0.24419 0.517681,0.38093 0.312562,0.12698 0.76187,0.12698 0.3614,0 0.654427,-0.0684 0.293027,-0.0684 0.459076,-0.14651 l 0.126978,0.76187 q -0.07814,0.0488 -0.224654,0.0977 -0.146513,0.0391 -0.332097,0.0684 -0.185584,0.0391 -0.40047,0.0586 -0.205119,0.0293 -0.400471,0.0293 z" />
507+ <path
508+ inkscape:connector-curvature="0"
509+ id="path3507"
510+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
511+ d="m 43.370739,279.74716 v -7.42335 l 0.908384,-0.15628 v 2.59817 q 0.253956,-0.0977 0.537216,-0.14651 0.293027,-0.0586 0.576286,-0.0586 0.60559,0 1.00606,0.17582 0.40047,0.16605 0.634892,0.47861 0.244189,0.3028 0.341865,0.73257 0.09768,0.42977 0.09768,0.94745 v 2.85213 h -0.908383 v -2.65678 q 0,-0.46884 -0.06837,-0.80094 -0.05861,-0.33209 -0.205119,-0.53721 -0.146514,-0.20512 -0.390703,-0.29303 -0.244189,-0.0977 -0.605589,-0.0977 -0.146514,0 -0.302795,0.0195 -0.156281,0.0195 -0.302794,0.0488 -0.136746,0.0195 -0.253957,0.0488 -0.107443,0.0293 -0.156281,0.0488 v 4.21959 z" />
512+ <path
513+ inkscape:connector-curvature="0"
514+ id="path3509"
515+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
516+ d="m 48.658044,277.21736 q 0,-0.67396 0.195351,-1.17211 0.195351,-0.50791 0.517681,-0.84001 0.32233,-0.33209 0.742335,-0.49814 0.420006,-0.16605 0.859546,-0.16605 1.025595,0 1.572579,0.64466 0.546983,0.63489 0.546983,1.94374 0,0.0586 0,0.15628 0,0.0879 -0.0098,0.16605 h -3.477254 q 0.05861,0.79118 0.459075,1.20141 0.400471,0.41024 1.250249,0.41024 0.478611,0 0.800941,-0.0781 0.332097,-0.0879 0.498146,-0.16605 l 0.126978,0.76187 q -0.166049,0.0879 -0.586054,0.18559 -0.410238,0.0977 -0.937687,0.0977 -0.664194,0 -1.152573,-0.19535 -0.47861,-0.20512 -0.791172,-0.55675 -0.312563,-0.35163 -0.468844,-0.83024 -0.146513,-0.48838 -0.146513,-1.06467 z m 3.487021,-0.49814 q 0.0098,-0.61536 -0.312562,-1.00606 -0.312562,-0.40047 -0.869313,-0.40047 -0.312562,0 -0.556752,0.12697 -0.234421,0.11722 -0.40047,0.31257 -0.166049,0.19535 -0.263724,0.4493 -0.08791,0.25396 -0.117211,0.51769 z" />
517+ <path
518+ inkscape:connector-curvature="0"
519+ id="path3511"
520+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:6.10472965px;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.24418919px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
521+ d="m 56.27278,274.56058 q 0.117211,0 0.263725,0.0195 0.156281,0.01 0.302794,0.0391 0.146514,0.0195 0.263725,0.0488 0.126978,0.0195 0.185584,0.0391 l -0.156282,0.79117 q -0.107443,-0.0391 -0.3614,-0.0879 -0.244189,-0.0586 -0.634891,-0.0586 -0.253957,0 -0.507914,0.0586 -0.244189,0.0488 -0.32233,0.0684 v 4.26843 h -0.908384 v -4.86425 q 0.32233,-0.11721 0.800941,-0.21488 0.478611,-0.10745 1.074432,-0.10745 z" />
522+ </g>
523+ </g>
524+</svg>
525
526=== added directory 'po'
527=== added file 'po/CMakeLists.txt'
528--- po/CMakeLists.txt 1970-01-01 00:00:00 +0000
529+++ po/CMakeLists.txt 2016-09-20 21:26:50 +0000
530@@ -0,0 +1,39 @@
531+include(FindGettext)
532+find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
533+find_program(INTLTOOL_UPDATE intltool-update)
534+
535+set(GETTEXT_PACKAGE ${PROJECT_NAME})
536+set(POT_FILE ${GETTEXT_PACKAGE}.pot)
537+file(GLOB POFILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.po)
538+
539+# Creates POTFILES
540+add_custom_target(POTFILES ALL
541+ COMMENT "Generating POTFILES"
542+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/genpotfiles.sh ${CMAKE_SOURCE_DIR}
543+)
544+
545+# Creates the .pot file containing the translations template
546+set(INTLTOOL_ENV
547+ XGETTEXT="${GETTEXT_XGETTEXT_EXECUTABLE}"
548+ XGETTEXT_ARGS="--keyword=Gettext;--keyword=NGettext:1,2;--keyword=tr;--keyword=tr:1,2;--keyword=N_"
549+ srcdir="${CMAKE_CURRENT_SOURCE_DIR}"
550+)
551+add_custom_target(${POT_FILE}
552+ COMMENT "Generating translation template"
553+ COMMAND ${INTLTOOL_ENV} ${INTLTOOL_UPDATE} --gettext-package ${GETTEXT_PACKAGE} --pot
554+ COMMAND cp -f ${POT_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/
555+ DEPENDS POTFILES
556+)
557+
558+# Builds the binary translations catalog for each language
559+# it finds source translations (*.po) for
560+foreach(POFILE ${POFILES})
561+ string(REPLACE ".po" "" LANG ${POFILE})
562+ list(APPEND PO_FILES "${POFILE}")
563+ gettext_process_po_files(${LANG} ALL PO_FILES "${POFILE}")
564+ set(INSTALL_DIR ${CMAKE_INSTALL_LOCALEDIR}/${LANG}/LC_MESSAGES)
565+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo
566+ DESTINATION ${INSTALL_DIR}
567+ RENAME ${GETTEXT_PACKAGE}.mo
568+ )
569+endforeach(POFILE)
570
571=== added file 'po/POTFILES.in'
572--- po/POTFILES.in 1970-01-01 00:00:00 +0000
573+++ po/POTFILES.in 2016-09-20 21:26:50 +0000
574@@ -0,0 +1,1 @@
575+data/bad-url.qml
576
577=== added file 'po/genpotfiles.sh'
578--- po/genpotfiles.sh 1970-01-01 00:00:00 +0000
579+++ po/genpotfiles.sh 2016-09-20 21:26:50 +0000
580@@ -0,0 +1,6 @@
581+#!/bin/sh
582+
583+sed '/^#/d
584+ s/^[[].*] *//
585+ /^[ ]*$/d' \
586+ "`dirname ${0}`/POTFILES.in" | sed '$!s/$/ \\/' > POTFILES
587
588=== modified file 'service/CMakeLists.txt'
589--- service/CMakeLists.txt 2015-06-11 21:38:13 +0000
590+++ service/CMakeLists.txt 2016-09-20 21:26:50 +0000
591@@ -47,15 +47,20 @@
592 overlay-tracker.cpp
593 overlay-tracker-iface.h
594 overlay-tracker-mir.h
595- overlay-tracker-mir.cpp)
596+ overlay-tracker-mir.cpp
597+ scope-checker-facade.h
598+ scope-checker.h
599+ scope-checker.cpp)
600
601 target_link_libraries(dispatcher-lib
602 url-db-lib
603 service-generated
604 -pthread
605+ ${APPARMOR_LIBRARIES}
606 ${GLIB2_LIBRARIES}
607 ${GOBJECT2_LIBRARIES}
608 ${GIO2_LIBRARIES}
609+ ${SCOPES_LIBRARIES}
610 ${SQLITE_LIBRARIES}
611 ${UBUNTU_APP_LAUNCH_LIBRARIES}
612 )
613@@ -106,14 +111,6 @@
614 target_link_libraries(update-directory ${GIO2_LIBRARIES} ${JSONGLIB_LIBRARIES} url-db-lib)
615
616 ###########################
617-# URL Overlay Exec Tool
618-###########################
619-
620-add_executable(url-overlay-exec-tool url-overlay.c recoverable-problem.c)
621-set_target_properties(url-overlay-exec-tool PROPERTIES OUTPUT_NAME "exec-tool")
622-target_link_libraries(url-overlay-exec-tool ${GIO2_LIBRARIES} ${UBUNTU_APP_LAUNCH_LIBRARIES} ${CLICK_LIBRARIES})
623-
624-###########################
625 # Installation
626 ###########################
627
628@@ -122,8 +119,9 @@
629 RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/url-dispatcher"
630 )
631
632-install(
633- TARGETS url-overlay-exec-tool
634- RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/ubuntu-app-launch/url-overlay"
635-)
636+###########################
637+# Exec Tools
638+###########################
639
640+add_subdirectory(url-overlay)
641+add_subdirectory(bad-url)
642
643=== added directory 'service/bad-url'
644=== added file 'service/bad-url/CMakeLists.txt'
645--- service/bad-url/CMakeLists.txt 1970-01-01 00:00:00 +0000
646+++ service/bad-url/CMakeLists.txt 2016-09-20 21:26:50 +0000
647@@ -0,0 +1,14 @@
648+###########################
649+# Bad URL Exec Tool
650+###########################
651+
652+add_definitions( -DQML_BAD_URL="${CMAKE_INSTALL_FULL_DATADIR}/url-dispatcher/bad-url.qml" )
653+add_executable(bad-url-exec-tool exec-tool.c)
654+set_target_properties(bad-url-exec-tool PROPERTIES OUTPUT_NAME "exec-tool")
655+target_link_libraries(bad-url-exec-tool ${GIO2_LIBRARIES} ${UBUNTU_APP_LAUNCH_LIBRARIES})
656+
657+install(
658+ TARGETS bad-url-exec-tool
659+ RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/ubuntu-app-launch/bad-url"
660+)
661+
662
663=== added file 'service/bad-url/exec-tool.c'
664--- service/bad-url/exec-tool.c 1970-01-01 00:00:00 +0000
665+++ service/bad-url/exec-tool.c 2016-09-20 21:26:50 +0000
666@@ -0,0 +1,42 @@
667+/*
668+ * Copyright © 2015 Canonical Ltd.
669+ *
670+ * This program is free software: you can redistribute it and/or modify it
671+ * under the terms of the GNU General Public License version 3, as published
672+ * by the Free Software Foundation.
673+ *
674+ * This program is distributed in the hope that it will be useful, but
675+ * WITHOUT ANY WARRANTY; without even the implied warranties of
676+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
677+ * PURPOSE. See the GNU General Public License for more details.
678+ *
679+ * You should have received a copy of the GNU General Public License along
680+ * with this program. If not, see <http://www.gnu.org/licenses/>.
681+ *
682+ * Authors:
683+ * Ted Gould <ted.gould@canonical.com>
684+ */
685+
686+#include <gio/gio.h>
687+#include <ubuntu-app-launch.h>
688+
689+int
690+main (int argc, char * argv[])
691+{
692+ GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
693+ g_return_val_if_fail(bus != NULL, -1);
694+
695+ gchar * exec = g_strdup_printf("qmlscene %s %s", QML_BAD_URL, g_getenv("APP_URIS"));
696+
697+ gboolean sended = ubuntu_app_launch_helper_set_exec(exec, NULL);
698+ g_free(exec);
699+
700+ /* Ensuring the messages get on the bus before we quit */
701+ g_dbus_connection_flush_sync(bus, NULL, NULL);
702+ g_clear_object(&bus);
703+
704+ if (sended)
705+ return 0;
706+ else
707+ return -1;
708+}
709
710=== modified file 'service/dispatcher.c'
711--- service/dispatcher.c 2015-09-03 21:50:06 +0000
712+++ service/dispatcher.c 2016-09-20 21:26:50 +0000
713@@ -23,10 +23,12 @@
714 #include "dispatcher.h"
715 #include "service-iface.h"
716 #include "recoverable-problem.h"
717+#include "scope-checker.h"
718 #include "url-db.h"
719
720 /* Globals */
721 static OverlayTracker * tracker = NULL;
722+static ScopeChecker * checker = NULL;
723 static GCancellable * cancellable = NULL;
724 static ServiceIfaceComCanonicalURLDispatcher * skel = NULL;
725 static GRegex * applicationre = NULL;
726@@ -73,6 +75,10 @@
727 g_variant_get(pid_tuple, "(u)", &pid);
728 g_variant_unref(pid_tuple);
729
730+ /* Popup the bad url dialog */
731+ overlay_tracker_badurl(tracker, pid, badurl);
732+
733+ /* Report recoverable error */
734 const gchar * additional[3] = {
735 "BadURL",
736 badurl,
737@@ -151,6 +157,11 @@
738 gboolean
739 send_to_dash (const gchar * url)
740 {
741+ if (url == NULL) {
742+ g_warning("Can not send nothing to the dash");
743+ return FALSE;
744+ }
745+
746 GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
747 g_return_val_if_fail(bus != NULL, FALSE);
748
749@@ -210,13 +221,109 @@
750 return TRUE;
751 }
752
753+/* Queries Upstart for the PID of a given upstart job */
754+pid_t
755+pid_for_upstart_job (GDBusConnection * conn, const gchar* jobname)
756+{
757+ GError* error = NULL;
758+
759+ if (jobname == NULL) {
760+ return 0;
761+ }
762+
763+ GVariant* retval = g_dbus_connection_call_sync(
764+ conn,
765+ "com.ubuntu.Upstart",
766+ "/com/ubuntu/Upstart",
767+ "com.ubuntu.Upstart0_6",
768+ "GetJobByName",
769+ g_variant_new("(s)", jobname),
770+ G_VARIANT_TYPE("(o)"),
771+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
772+ -1, /* timeout */
773+ NULL, /* cancel */
774+ &error);
775+
776+ if (error != NULL) {
777+ g_warning("Unable to get path for job '%s': %s", jobname, error->message);
778+ g_error_free(error);
779+ return 0;
780+ }
781+
782+ gchar* path = NULL;
783+ g_variant_get(retval, "(o)", &path);
784+ g_variant_unref(retval);
785+
786+ retval = g_dbus_connection_call_sync(
787+ conn,
788+ "com.ubuntu.Upstart",
789+ path,
790+ "com.ubuntu.Upstart0_6.Job",
791+ "GetInstanceByName",
792+ g_variant_new("(s)", ""),
793+ G_VARIANT_TYPE("(o)"),
794+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
795+ -1, /* timeout */
796+ NULL, /* cancel */
797+ &error);
798+
799+ g_free(path);
800+
801+ if (error != NULL) {
802+ g_warning("Unable to get instance for job '%s': %s", jobname, error->message);
803+ g_error_free(error);
804+ return 0;
805+ }
806+
807+ g_variant_get(retval, "(o)", &path);
808+ g_variant_unref(retval);
809+
810+ retval = g_dbus_connection_call_sync(
811+ conn,
812+ "com.ubuntu.Upstart",
813+ path,
814+ "org.freedesktop.DBus.Properties",
815+ "Get",
816+ g_variant_new("(ss)", "com.ubuntu.Upstart0_6.Instance", "processes"),
817+ G_VARIANT_TYPE("(v)"),
818+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
819+ -1, /* timeout */
820+ NULL, /* cancel */
821+ &error);
822+
823+ g_free(path);
824+
825+ if (error != NULL) {
826+ g_warning("Unable to get processes for job '%s': %s", jobname, error->message);
827+ g_error_free(error);
828+ return 0;
829+ }
830+
831+ GPid pid = 0;
832+ GVariant* variant = g_variant_get_child_value(retval, 0);
833+ GVariant* array = g_variant_get_variant(variant);
834+ if (g_variant_n_children(array) > 0) {
835+ /* (si) */
836+ GVariant* firstitem = g_variant_get_child_value(array, 0);
837+ GVariant* vpid = g_variant_get_child_value(firstitem, 1);
838+ pid = g_variant_get_int32(vpid);
839+ g_variant_unref(vpid);
840+ g_variant_unref(firstitem);
841+ }
842+ g_variant_unref(variant);
843+ g_variant_unref(array);
844+ g_variant_unref(retval);
845+
846+ return pid;
847+}
848+
849+
850 /* Handles setting up the overlay with the URL */
851 gboolean
852 dispatcher_send_to_overlay (const gchar * app_id, const gchar * url, GDBusConnection * conn, const gchar * sender)
853 {
854 GError * error = NULL;
855
856- /* TODO: Detect if a scope is what we need to overlay on */
857 GVariant * callret = g_dbus_connection_call_sync(conn,
858 "org.freedesktop.DBus",
859 "/",
860@@ -239,6 +346,12 @@
861 g_variant_get_child(callret, 0, "u", &pid);
862 g_variant_unref(callret);
863
864+ /* If it is from a scope we need to overlay onto the
865+ dash instead */
866+ if (scope_checker_is_scope_pid(checker, pid)) {
867+ pid = pid_for_upstart_job(conn, "unity8-dash");
868+ }
869+
870 return overlay_tracker_add(tracker, app_id, pid, url);
871 }
872
873@@ -437,7 +550,17 @@
874
875 *out_appid = ubuntu_app_launch_triplet_to_app_id(package, app, version);
876 if (*out_appid != NULL) {
877- retval = TRUE;
878+ /* Look at the current version of the app and ensure
879+ we're not asking for an older version */
880+ gchar * testappid = ubuntu_app_launch_triplet_to_app_id(package, app, NULL);
881+ if (g_strcmp0(*out_appid, testappid) != 0) {
882+ retval = FALSE;
883+ g_clear_pointer(out_appid, g_free);
884+ } else {
885+ retval = TRUE;
886+ }
887+
888+ g_free(testappid);
889 }
890
891 g_free(package);
892@@ -483,6 +606,17 @@
893 }
894 }
895
896+ if (g_strcmp0(protocol, "scope") == 0) {
897+ /* Add a check for the scope if we can do that, since it is
898+ a system URL that we can do more checking on */
899+ if (!scope_checker_is_scope(checker, domain)) {
900+ found = FALSE;
901+ g_clear_pointer(out_appid, g_free);
902+ if (out_url != NULL)
903+ g_clear_pointer(out_url, g_free);
904+ }
905+ }
906+
907 g_free(protocol);
908 g_free(domain);
909
910@@ -517,7 +651,7 @@
911
912 if (error != NULL) {
913 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
914- g_error("Unable to connect to D-Bus: %s", error->message);
915+ g_error("Unable to connect to D-Bus");
916 g_main_loop_quit(mainloop);
917 }
918 g_error_free(error);
919@@ -547,17 +681,18 @@
920
921 /* Initialize all the globals */
922 gboolean
923-dispatcher_init (GMainLoop * mainloop, OverlayTracker * intracker)
924+dispatcher_init (GMainLoop * mainloop, OverlayTracker * intracker, ScopeChecker * inchecker)
925 {
926 tracker = intracker;
927+ checker = inchecker;
928 cancellable = g_cancellable_new();
929
930 urldb = url_db_create_database();
931 g_return_val_if_fail(urldb != NULL, FALSE);
932
933 applicationre = g_regex_new("^application:///([a-zA-Z0-9_\\.-]*)\\.desktop$", 0, 0, NULL);
934- appidre = g_regex_new("^appid://([a-z0-9\\.-]*)/([a-zA-Z0-9-]*)/([a-zA-Z0-9\\.-]*)$", 0, 0, NULL);
935- genericre = g_regex_new("^([a-z][a-z0-9]*):(?://(?:.*@)?([a-zA-Z0-9\\.-]*)(?::[0-9]*)?/?)?(.*)?$", 0, 0, NULL);
936+ appidre = g_regex_new("^appid://([a-z0-9\\.-]*)/([a-zA-Z0-9-\\.]*)/([a-zA-Z0-9\\.-]*)$", 0, 0, NULL);
937+ genericre = g_regex_new("^([a-z][a-z0-9]*):(?://(?:.*@)?([a-zA-Z0-9\\.-_]*)(?::[0-9]*)?/?)?(.*)?$", 0, 0, NULL);
938 intentre = g_regex_new("^intent://.*package=([a-zA-Z0-9\\.]*);.*$", 0, 0, NULL);
939
940 g_bus_get(G_BUS_TYPE_SESSION, cancellable, bus_got, mainloop);
941
942=== modified file 'service/dispatcher.h'
943--- service/dispatcher.h 2015-06-11 21:47:17 +0000
944+++ service/dispatcher.h 2016-09-20 21:26:50 +0000
945@@ -22,10 +22,11 @@
946
947 #include <gio/gio.h>
948 #include "overlay-tracker.h"
949+#include "scope-checker.h"
950
951 G_BEGIN_DECLS
952
953-gboolean dispatcher_init (GMainLoop * mainloop, OverlayTracker * tracker);
954+gboolean dispatcher_init (GMainLoop * mainloop, OverlayTracker * tracker, ScopeChecker * checker);
955 gboolean dispatcher_shutdown ();
956 gboolean dispatcher_url_to_appid (const gchar * url, gchar ** out_appid, const gchar ** out_url);
957 gboolean dispatcher_appid_restrict (const gchar * appid, const gchar * package);
958
959=== modified file 'service/overlay-tracker-iface.h'
960--- service/overlay-tracker-iface.h 2015-05-19 20:24:47 +0000
961+++ service/overlay-tracker-iface.h 2016-09-20 21:26:50 +0000
962@@ -23,4 +23,5 @@
963 public:
964 virtual ~OverlayTrackerIface() = default;
965 virtual bool addOverlay (const char * appid, unsigned long pid, const char * url) = 0;
966+ virtual bool badUrl (unsigned long pid, const char * url) = 0;
967 };
968
969=== modified file 'service/overlay-tracker-mir.cpp'
970--- service/overlay-tracker-mir.cpp 2015-06-11 21:47:17 +0000
971+++ service/overlay-tracker-mir.cpp 2016-09-20 21:26:50 +0000
972@@ -20,16 +20,20 @@
973 #include "overlay-tracker-mir.h"
974 #include <ubuntu-app-launch.h>
975
976-static const char * HELPER_TYPE = "url-overlay";
977+static const char * OVERLAY_HELPER_TYPE = "url-overlay";
978+static const char * BAD_URL_HELPER_TYPE = "bad-url";
979+static const char * BAD_URL_APP_ID = "url-dispatcher-bad-url-helper";
980
981 OverlayTrackerMir::OverlayTrackerMir ()
982 : thread([this] {
983 /* Setup Helper Observer */
984- ubuntu_app_launch_observer_add_helper_stop(untrustedHelperStoppedStatic, HELPER_TYPE, this);
985+ ubuntu_app_launch_observer_add_helper_stop(overlayHelperStoppedStatic, OVERLAY_HELPER_TYPE, this);
986+ ubuntu_app_launch_observer_add_helper_stop(overlayHelperStoppedStatic, BAD_URL_HELPER_TYPE, this);
987 },
988 [this] {
989 /* Remove Helper Observer */
990- ubuntu_app_launch_observer_delete_helper_stop(untrustedHelperStoppedStatic, HELPER_TYPE, this);
991+ ubuntu_app_launch_observer_delete_helper_stop(overlayHelperStoppedStatic, OVERLAY_HELPER_TYPE, this);
992+ ubuntu_app_launch_observer_delete_helper_stop(overlayHelperStoppedStatic, BAD_URL_HELPER_TYPE, this);
993 })
994 {
995 mir = std::shared_ptr<MirConnection>([] {
996@@ -52,8 +56,10 @@
997 OverlayTrackerMir::~OverlayTrackerMir ()
998 {
999 thread.executeOnThread<bool>([this] {
1000- while (!ongoingSessions.empty()) {
1001- removeSession(std::get<2>(*ongoingSessions.begin()).get());
1002+ for (auto& sessionType : ongoingSessions) {
1003+ while (!sessionType.second.empty()) {
1004+ removeSession(sessionType.first, sessionType.second.begin()->session.get());
1005+ }
1006 }
1007
1008 return true;
1009@@ -65,53 +71,75 @@
1010 bool
1011 OverlayTrackerMir::addOverlay (const char * appid, unsigned long pid, const char * url)
1012 {
1013- std::string sappid(appid);
1014+ return addOverlayCore(OVERLAY_HELPER_TYPE, appid, pid, url, overlaySessionStateChangedStatic);
1015+}
1016+
1017+bool
1018+OverlayTrackerMir::addOverlayCore (const char * helper_id, const char * appid, unsigned long pid, const char * url, void (*stateChangedFunction) (MirPromptSession*, MirPromptSessionState, void *))
1019+{
1020+ OverlayData data;
1021+ data.appid = appid;
1022 std::string surl(url);
1023
1024- return thread.executeOnThread<bool>([this, sappid, pid, surl] {
1025- g_debug("Setting up over lay for PID %d with '%s'", pid, sappid.c_str());
1026+ return thread.executeOnThread<bool>([this, helper_id, &data, pid, surl, stateChangedFunction] {
1027+ g_debug("Setting up over lay for PID %d with '%s'", (int)pid, data.appid.c_str());
1028
1029- auto session = std::shared_ptr<MirPromptSession>(
1030- mir_connection_create_prompt_session_sync(mir.get(), pid, sessionStateChangedStatic, this),
1031+ data.session = std::shared_ptr<MirPromptSession>(
1032+ mir_connection_create_prompt_session_sync(mir.get(), pid, stateChangedFunction, this),
1033 [] (MirPromptSession * session) { if (session) mir_prompt_session_release_sync(session); });
1034- if (!session) {
1035- g_critical("Unable to create trusted prompt session for %d with appid '%s'", pid, sappid.c_str());
1036+ if (!data.session) {
1037+ g_critical("Unable to create trusted prompt session for %d with appid '%s'", (int)pid, data.appid.c_str());
1038 return false;
1039 }
1040-
1041+
1042 std::array<const char *, 2> urls { surl.c_str(), nullptr };
1043- auto instance = ubuntu_app_launch_start_session_helper(HELPER_TYPE, session.get(), sappid.c_str(), urls.data());
1044+ auto instance = ubuntu_app_launch_start_session_helper(helper_id, data.session.get(), data.appid.c_str(), urls.data());
1045 if (instance == nullptr) {
1046- g_critical("Unable to start helper for %d with appid '%s'", pid, sappid.c_str());
1047+ g_critical("Unable to start helper for %d with appid '%s'", (int)pid, data.appid.c_str());
1048 return false;
1049 }
1050+ data.instanceid = instance;
1051
1052- ongoingSessions.emplace(std::make_tuple(sappid, std::string(instance), session));
1053+ ongoingSessions[helper_id].push_back(data);
1054 g_free(instance);
1055 return true;
1056 });
1057 }
1058
1059-void
1060-OverlayTrackerMir::sessionStateChangedStatic (MirPromptSession * session, MirPromptSessionState state, void * user_data)
1061-{
1062- reinterpret_cast<OverlayTrackerMir *>(user_data)->sessionStateChanged(session, state);
1063-}
1064-
1065-void
1066-OverlayTrackerMir::removeSession (MirPromptSession * session)
1067-{
1068- for (auto it = ongoingSessions.begin(); it != ongoingSessions.end(); it++) {
1069- if (std::get<2>(*it).get() == session) {
1070- ubuntu_app_launch_stop_multiple_helper(HELPER_TYPE, std::get<0>(*it).c_str(), std::get<1>(*it).c_str());
1071- ongoingSessions.erase(it);
1072+bool
1073+OverlayTrackerMir::badUrl (unsigned long pid, const char * url)
1074+{
1075+ return addOverlayCore(BAD_URL_HELPER_TYPE, BAD_URL_APP_ID, pid, url, badUrlSessionStateChangedStatic);
1076+}
1077+
1078+void
1079+OverlayTrackerMir::overlaySessionStateChangedStatic (MirPromptSession * session, MirPromptSessionState state, void * user_data)
1080+{
1081+ reinterpret_cast<OverlayTrackerMir *>(user_data)->sessionStateChanged(session, state, OVERLAY_HELPER_TYPE);
1082+}
1083+
1084+void
1085+OverlayTrackerMir::badUrlSessionStateChangedStatic (MirPromptSession * session, MirPromptSessionState state, void * user_data)
1086+{
1087+ reinterpret_cast<OverlayTrackerMir *>(user_data)->sessionStateChanged(session, state, BAD_URL_HELPER_TYPE);
1088+}
1089+
1090+void
1091+OverlayTrackerMir::removeSession (const std::string &type, MirPromptSession * session)
1092+{
1093+ g_debug("Removing session: %p", (void*)session);
1094+
1095+ for (auto it = ongoingSessions[type].begin(); it != ongoingSessions[type].end(); it++) {
1096+ if (it->session.get() == session) {
1097+ ubuntu_app_launch_stop_multiple_helper(type.c_str(), it->appid.c_str(), it->instanceid.c_str());
1098+ ongoingSessions[type].erase(it);
1099 break;
1100 }
1101 }
1102 }
1103
1104 void
1105-OverlayTrackerMir::sessionStateChanged (MirPromptSession * session, MirPromptSessionState state)
1106+OverlayTrackerMir::sessionStateChanged (MirPromptSession * session, MirPromptSessionState state, const std::string &type)
1107 {
1108 if (state != mir_prompt_session_state_stopped) {
1109 /* We only care about the stopped state */
1110@@ -120,23 +148,24 @@
1111
1112 /* Executing on the Mir thread, which is nice and all, but we
1113 want to get back on our thread */
1114- thread.executeOnThread([this, session]() {
1115- removeSession(session);
1116+ thread.executeOnThread([this, type, session]() {
1117+ removeSession(type, session);
1118 });
1119 }
1120
1121 void
1122-OverlayTrackerMir::untrustedHelperStoppedStatic (const gchar * appid, const gchar * instanceid, const gchar * helpertype, gpointer user_data)
1123+OverlayTrackerMir::overlayHelperStoppedStatic (const gchar * appid, const gchar * instanceid, const gchar * helpertype, gpointer user_data)
1124 {
1125- reinterpret_cast<OverlayTrackerMir *>(user_data)->untrustedHelperStopped(appid, instanceid, helpertype);
1126+ reinterpret_cast<OverlayTrackerMir *>(user_data)->overlayHelperStopped(appid, instanceid, helpertype);
1127 }
1128
1129 void
1130-OverlayTrackerMir::untrustedHelperStopped(const gchar * appid, const gchar * instanceid, const gchar * helpertype)
1131+OverlayTrackerMir::overlayHelperStopped(const gchar * appid, const gchar * instanceid, const gchar * helpertype)
1132 {
1133 /* This callback will happen on our thread already, we don't need
1134 to proxy it on */
1135- if (g_strcmp0(helpertype, HELPER_TYPE) != 0) {
1136+ if (g_strcmp0(helpertype, OVERLAY_HELPER_TYPE) != 0
1137+ && g_strcmp0(helpertype, BAD_URL_HELPER_TYPE) != 0) {
1138 return;
1139 }
1140
1141@@ -144,10 +173,11 @@
1142 std::string sappid(appid);
1143 std::string sinstanceid(instanceid);
1144
1145- for (auto it = ongoingSessions.begin(); it != ongoingSessions.end(); it++) {
1146- if (std::get<0>(*it) == sappid && std::get<1>(*it) == sinstanceid) {
1147- ongoingSessions.erase(it);
1148+ for (auto it = ongoingSessions[helpertype].begin(); it != ongoingSessions[helpertype].end(); it++) {
1149+ if (it->appid == sappid && it->instanceid == sinstanceid) {
1150+ ongoingSessions[helpertype].erase(it);
1151 break;
1152 }
1153 }
1154 }
1155+
1156
1157=== modified file 'service/overlay-tracker-mir.h'
1158--- service/overlay-tracker-mir.h 2015-06-11 21:50:05 +0000
1159+++ service/overlay-tracker-mir.h 2016-09-20 21:26:50 +0000
1160@@ -19,7 +19,9 @@
1161
1162 #pragma once
1163
1164+#include <map>
1165 #include <set>
1166+#include <vector>
1167
1168 #include <mir_toolkit/mir_connection.h>
1169 #include <mir_toolkit/mir_prompt_session.h>
1170@@ -29,21 +31,33 @@
1171
1172 class OverlayTrackerMir : public OverlayTrackerIface {
1173 private:
1174+ struct OverlayData {
1175+ std::string appid;
1176+ std::string instanceid;
1177+ std::shared_ptr<MirPromptSession> session;
1178+ };
1179+
1180 GLib::ContextThread thread;
1181 std::shared_ptr<MirConnection> mir;
1182- std::set<std::tuple<std::string, std::string, std::shared_ptr<MirPromptSession>>> ongoingSessions;
1183+ std::map<std::string, std::vector<OverlayData>> ongoingSessions;
1184
1185 public:
1186 OverlayTrackerMir ();
1187 ~OverlayTrackerMir ();
1188 bool addOverlay (const char * appid, unsigned long pid, const char * url) override;
1189+ bool badUrl (unsigned long pid, const char * url) override;
1190
1191 private:
1192- void removeSession (MirPromptSession * session);
1193-
1194- static void sessionStateChangedStatic (MirPromptSession * session, MirPromptSessionState state, void * user_data);
1195- void sessionStateChanged (MirPromptSession * session, MirPromptSessionState state);
1196-
1197- static void untrustedHelperStoppedStatic (const gchar * appid, const gchar * instanceid, const gchar * helpertype, gpointer user_data);
1198- void untrustedHelperStopped(const gchar * appid, const gchar * instanceid, const gchar * helpertype);
1199+ /* Overlay Functions */
1200+ void removeSession (const std::string &type, MirPromptSession * session);
1201+
1202+ static void badUrlSessionStateChangedStatic (MirPromptSession * session, MirPromptSessionState state, void * user_data);
1203+ static void overlaySessionStateChangedStatic (MirPromptSession * session, MirPromptSessionState state, void * user_data);
1204+ void sessionStateChanged (MirPromptSession * session, MirPromptSessionState state, const std::string &type);
1205+
1206+ static void overlayHelperStoppedStatic (const gchar * appid, const gchar * instanceid, const gchar * helpertype, gpointer user_data);
1207+ void overlayHelperStopped(const gchar * appid, const gchar * instanceid, const gchar * helpertype);
1208+
1209+ bool addOverlayCore (const gchar * helperid, const gchar * appid, unsigned long pid, const gchar * url, void (*stateChangedFunction) (MirPromptSession*, MirPromptSessionState, void *));
1210+
1211 };
1212
1213=== modified file 'service/overlay-tracker.cpp'
1214--- service/overlay-tracker.cpp 2015-06-11 21:47:17 +0000
1215+++ service/overlay-tracker.cpp 2016-09-20 21:26:50 +0000
1216@@ -52,3 +52,12 @@
1217
1218 return reinterpret_cast<OverlayTrackerIface *>(tracker)->addOverlay(appid, pid, url) ? TRUE : FALSE;
1219 }
1220+
1221+gboolean
1222+overlay_tracker_badurl (OverlayTracker * tracker, unsigned long pid, const gchar * url) {
1223+ g_return_val_if_fail(tracker != nullptr, FALSE);
1224+ g_return_val_if_fail(pid != 0, FALSE);
1225+ g_return_val_if_fail(url != nullptr, FALSE);
1226+
1227+ return reinterpret_cast<OverlayTrackerIface *>(tracker)->badUrl(pid, url) ? TRUE : FALSE;
1228+}
1229
1230=== modified file 'service/overlay-tracker.h'
1231--- service/overlay-tracker.h 2015-06-11 21:47:17 +0000
1232+++ service/overlay-tracker.h 2016-09-20 21:26:50 +0000
1233@@ -25,4 +25,5 @@
1234 OverlayTracker * overlay_tracker_new ();
1235 void overlay_tracker_delete (OverlayTracker * tracker);
1236 gboolean overlay_tracker_add (OverlayTracker * tracker, const char * appid, unsigned long pid, const char * url);
1237+gboolean overlay_tracker_badurl (OverlayTracker * tracker, unsigned long pid, const char * url);
1238
1239
1240=== added file 'service/scope-checker-facade.h'
1241--- service/scope-checker-facade.h 1970-01-01 00:00:00 +0000
1242+++ service/scope-checker-facade.h 2016-09-20 21:26:50 +0000
1243@@ -0,0 +1,27 @@
1244+/**
1245+ * Copyright © 2016 Canonical, Ltd.
1246+ *
1247+ * This program is free software: you can redistribute it and/or modify it under
1248+ * the terms of the GNU Lesser General Public License version 3, as published by
1249+ * the Free Software Foundation.
1250+ *
1251+ * This program is distributed in the hope that it will be useful, but WITHOUT
1252+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1253+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1254+ * Lesser General Public License for more details.
1255+ *
1256+ * You should have received a copy of the GNU Lesser General Public License
1257+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1258+ *
1259+ */
1260+
1261+#pragma once
1262+
1263+#include <unity-scopes.h>
1264+
1265+class RuntimeFacade {
1266+public:
1267+ RuntimeFacade () = default;
1268+ virtual ~RuntimeFacade () = default;
1269+ virtual unity::scopes::RegistryProxy registry () = 0;
1270+};
1271
1272=== added file 'service/scope-checker.cpp'
1273--- service/scope-checker.cpp 1970-01-01 00:00:00 +0000
1274+++ service/scope-checker.cpp 2016-09-20 21:26:50 +0000
1275@@ -0,0 +1,114 @@
1276+/**
1277+ * Copyright © 2016 Canonical, Ltd.
1278+ *
1279+ * This program is free software: you can redistribute it and/or modify it under
1280+ * the terms of the GNU Lesser General Public License version 3, as published by
1281+ * the Free Software Foundation.
1282+ *
1283+ * This program is distributed in the hope that it will be useful, but WITHOUT
1284+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1285+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1286+ * Lesser General Public License for more details.
1287+ *
1288+ * You should have received a copy of the GNU Lesser General Public License
1289+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1290+ *
1291+ */
1292+
1293+extern "C" {
1294+#include "scope-checker.h"
1295+#include <sys/apparmor.h>
1296+#include <ubuntu-app-launch.h>
1297+}
1298+
1299+#include <unity-scopes.h>
1300+#include "scope-checker-facade.h"
1301+
1302+class RuntimeReal : public RuntimeFacade {
1303+public:
1304+ unity::scopes::Runtime::UPtr runtime;
1305+ RuntimeReal () {
1306+ runtime = unity::scopes::Runtime::create();
1307+ }
1308+
1309+ unity::scopes::RegistryProxy registry () override {
1310+ return runtime->registry();
1311+ }
1312+};
1313+
1314+ScopeChecker *
1315+scope_checker_new ()
1316+{
1317+ auto fu_runtime = new RuntimeReal();
1318+ return reinterpret_cast<ScopeChecker *>(fu_runtime);
1319+}
1320+
1321+void
1322+scope_checker_delete (ScopeChecker * checker)
1323+{
1324+ auto runtime = reinterpret_cast<RuntimeFacade *>(checker);
1325+ delete runtime;
1326+}
1327+
1328+bool
1329+scope_checker_is_scope (ScopeChecker * checker, const char * appid)
1330+{
1331+ if (checker == nullptr) {
1332+ g_warning("%s:%d: Checker is '(null)'", __FILE__, __LINE__);
1333+ return false;
1334+ }
1335+ if (appid == nullptr) {
1336+ g_warning("%s:%d: appid is '(null)'", __FILE__, __LINE__);
1337+ return false;
1338+ }
1339+
1340+ auto runtime = reinterpret_cast<RuntimeFacade *>(checker);
1341+
1342+ try {
1343+ auto registry = runtime->registry();
1344+ registry->get_metadata(appid);
1345+ return true;
1346+ } catch (unity::scopes::NotFoundException e) {
1347+ return false;
1348+ } catch (...) {
1349+ g_warning("Unable to read the Unity Scopes Registry");
1350+ return false;
1351+ }
1352+}
1353+
1354+bool
1355+scope_checker_is_scope_pid (ScopeChecker * checker, pid_t pid)
1356+{
1357+ if (pid == 0)
1358+ return false;
1359+
1360+ char * aa = nullptr;
1361+ if (aa_gettaskcon(pid, &aa, nullptr) != 0) {
1362+ return false;
1363+ }
1364+
1365+ if (aa == nullptr)
1366+ return false;
1367+
1368+ std::string appid(aa);
1369+ free(aa);
1370+
1371+ if (appid == "unconfined") {
1372+ /* We're not going to support unconfined scopes, too hard */
1373+ return false;
1374+ }
1375+
1376+ gchar * pkg = nullptr;
1377+ gchar * app = nullptr;
1378+ if (ubuntu_app_launch_app_id_parse(appid.c_str(), &pkg, &app, nullptr)) {
1379+ appid= pkg;
1380+ appid += "_";
1381+ appid += app;
1382+
1383+ g_free(pkg);
1384+ g_free(app);
1385+ }
1386+
1387+ g_debug("PID %d is short App ID %s", pid, appid.c_str());
1388+ return scope_checker_is_scope(checker, appid.c_str());
1389+}
1390
1391=== added file 'service/scope-checker.h'
1392--- service/scope-checker.h 1970-01-01 00:00:00 +0000
1393+++ service/scope-checker.h 2016-09-20 21:26:50 +0000
1394@@ -0,0 +1,29 @@
1395+/**
1396+ * Copyright © 2016 Canonical, Ltd.
1397+ *
1398+ * This program is free software: you can redistribute it and/or modify it under
1399+ * the terms of the GNU Lesser General Public License version 3, as published by
1400+ * the Free Software Foundation.
1401+ *
1402+ * This program is distributed in the hope that it will be useful, but WITHOUT
1403+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1404+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1405+ * Lesser General Public License for more details.
1406+ *
1407+ * You should have received a copy of the GNU Lesser General Public License
1408+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1409+ *
1410+ */
1411+
1412+#pragma once
1413+
1414+#include <sys/types.h>
1415+#include <stdbool.h>
1416+
1417+typedef struct _ScopeChecker ScopeChecker;
1418+
1419+ScopeChecker * scope_checker_new ();
1420+void scope_checker_delete (ScopeChecker * checker);
1421+bool scope_checker_is_scope (ScopeChecker * checker, const char * appid);
1422+bool scope_checker_is_scope_pid (ScopeChecker * checker, pid_t pid);
1423+
1424
1425=== modified file 'service/service.c'
1426--- service/service.c 2015-09-03 21:50:06 +0000
1427+++ service/service.c 2016-09-20 21:26:50 +0000
1428@@ -40,7 +40,14 @@
1429 guint term_source = g_unix_signal_add(SIGTERM, sig_term, mainloop);
1430
1431 OverlayTracker * tracker = overlay_tracker_new();
1432- if (!dispatcher_init(mainloop, tracker)) {
1433+
1434+ ScopeChecker * checker = NULL;
1435+ /* Allow disabing for testing */
1436+ if (g_getenv("URL_DISPATCHER_DISABLE_SCOPE_CHECKING") == NULL)
1437+ checker = scope_checker_new();
1438+
1439+ /* Initialize Dispatcher */
1440+ if (!dispatcher_init(mainloop, tracker, checker)) {
1441 return -1;
1442 }
1443
1444@@ -50,6 +57,7 @@
1445 /* Clean up globals */
1446 dispatcher_shutdown();
1447 overlay_tracker_delete(tracker);
1448+ scope_checker_delete(checker);
1449 g_source_remove(term_source);
1450 g_main_loop_unref(mainloop);
1451
1452
1453=== added directory 'service/url-overlay'
1454=== added file 'service/url-overlay/CMakeLists.txt'
1455--- service/url-overlay/CMakeLists.txt 1970-01-01 00:00:00 +0000
1456+++ service/url-overlay/CMakeLists.txt 2016-09-20 21:26:50 +0000
1457@@ -0,0 +1,14 @@
1458+
1459+###########################
1460+# URL Overlay Exec Tool
1461+###########################
1462+
1463+add_executable(url-overlay-exec-tool exec-tool.c ../recoverable-problem.c)
1464+set_target_properties(url-overlay-exec-tool PROPERTIES OUTPUT_NAME "exec-tool")
1465+target_link_libraries(url-overlay-exec-tool ${GIO2_LIBRARIES} ${UBUNTU_APP_LAUNCH_LIBRARIES} ${CLICK_LIBRARIES})
1466+
1467+install(
1468+ TARGETS url-overlay-exec-tool
1469+ RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/ubuntu-app-launch/url-overlay"
1470+)
1471+
1472
1473=== renamed file 'service/url-overlay.c' => 'service/url-overlay/exec-tool.c'
1474=== modified file 'tests/CMakeLists.txt'
1475--- tests/CMakeLists.txt 2015-06-11 21:38:13 +0000
1476+++ tests/CMakeLists.txt 2016-09-20 21:26:50 +0000
1477@@ -25,6 +25,8 @@
1478 ###########################
1479
1480 add_library(mock-lib STATIC
1481+ apparmor-mock.h
1482+ apparmor-mock.c
1483 recoverable-problem-mock.c
1484 ubuntu-app-launch-mock.h
1485 ubuntu-app-launch-mock.c)
1486@@ -62,6 +64,7 @@
1487 mock-lib
1488 gtest
1489 ${UBUNTU_APP_LAUNCH_LIBRARIES}
1490+ ${DBUSTEST_LIBRARIES}
1491 ${GTEST_LIBS})
1492
1493 add_test (dispatcher-test dispatcher-test)
1494
1495=== modified file 'tests/app-id-test.cc'
1496--- tests/app-id-test.cc 2015-05-15 21:24:15 +0000
1497+++ tests/app-id-test.cc 2016-09-20 21:26:50 +0000
1498@@ -23,6 +23,8 @@
1499 #include "ubuntu-app-launch-mock.h"
1500 #include "overlay-tracker-mock.h"
1501
1502+#include "ubuntu-app-launch/registry.h"
1503+
1504 class AppIdTest : public ::testing::Test
1505 {
1506 private:
1507@@ -33,9 +35,20 @@
1508
1509 protected:
1510 virtual void SetUp() {
1511+ /* Click DB Config */
1512 g_setenv("TEST_CLICK_DB", "click-db", TRUE);
1513 g_setenv("TEST_CLICK_USER", "test-user", TRUE);
1514
1515+ /* Make sure we don't use the local snapd */
1516+ g_setenv("UBUNTU_APP_LAUNCH_SNAPD_SOCKET", "/this/should/not/exist", TRUE);
1517+
1518+ /* UAL Desktop Hook check */
1519+ g_setenv("UBUNTU_APP_LAUNCH_LINK_FARM", CMAKE_SOURCE_DIR "/tests/ual-link-farm", TRUE);
1520+
1521+ /* XDG Data home for libertine */
1522+ g_setenv("XDG_DATA_HOME", CMAKE_SOURCE_DIR "/tests/xdg-data", TRUE);
1523+ g_setenv("XDG_CACHE_HOME", CMAKE_SOURCE_DIR "/tests/xdg-cache", TRUE);
1524+
1525 cachedir = g_build_filename(CMAKE_BINARY_DIR, "app-id-test-cache", nullptr);
1526 g_setenv("URL_DISPATCHER_CACHE_DIR", cachedir, TRUE);
1527
1528@@ -43,13 +56,14 @@
1529 g_test_dbus_up(testbus);
1530
1531 mainloop = g_main_loop_new(nullptr, FALSE);
1532- dispatcher_init(mainloop, reinterpret_cast<OverlayTracker *>(&tracker));
1533+ dispatcher_init(mainloop, reinterpret_cast<OverlayTracker *>(&tracker), nullptr);
1534
1535 return;
1536 }
1537
1538 virtual void TearDown() {
1539 dispatcher_shutdown();
1540+ ubuntu::app_launch::Registry::clearDefault();
1541
1542 /* Clean up queued events */
1543 while (g_main_pending()) {
1544@@ -88,6 +102,18 @@
1545 g_clear_pointer(&out_appid, g_free);
1546 out_url = nullptr;
1547
1548+ /* App ID with periods */
1549+ dispatcher_url_to_appid("appid://container-id/org.canonical.app1/0.0", &out_appid, &out_url);
1550+ ASSERT_STREQ("container-id_org.canonical.app1_0.0", out_appid);
1551+ EXPECT_EQ(nullptr, out_url);
1552+
1553+ dispatcher_send_to_app(out_appid, out_url);
1554+ EXPECT_STREQ("container-id_org.canonical.app1_0.0", ubuntu_app_launch_mock_get_last_app_id());
1555+
1556+ ubuntu_app_launch_mock_clear_last_app_id();
1557+ g_clear_pointer(&out_appid, g_free);
1558+ out_url = nullptr;
1559+
1560 /* No version at all */
1561 dispatcher_url_to_appid("appid://com.test.good/app1", &out_appid, &out_url);
1562
1563@@ -199,31 +225,3 @@
1564
1565 return;
1566 }
1567-
1568-TEST_F(AppIdTest, BadDirectory)
1569-{
1570- gchar * out_appid = nullptr;
1571- const gchar * out_url = nullptr;
1572-
1573- g_setenv("TEST_CLICK_DB", "not-click-db", TRUE);
1574-
1575- dispatcher_url_to_appid("appid://com.test.good/app1/current-user-version", &out_appid, &out_url);
1576-
1577- EXPECT_EQ(nullptr, out_appid);
1578- EXPECT_EQ(nullptr, out_url);
1579-
1580- return;
1581-}
1582-
1583-TEST_F(AppIdTest, BadUser)
1584-{
1585- gchar * out_appid = nullptr;
1586- const gchar * out_url = nullptr;
1587-
1588- g_setenv("TEST_CLICK_USER", "not-test-user", TRUE);
1589-
1590- dispatcher_url_to_appid("appid://com.test.good/app1/current-user-version", &out_appid, &out_url);
1591-
1592- EXPECT_EQ(nullptr, out_appid);
1593- EXPECT_EQ(nullptr, out_url);
1594-}
1595
1596=== added file 'tests/apparmor-mock.c'
1597--- tests/apparmor-mock.c 1970-01-01 00:00:00 +0000
1598+++ tests/apparmor-mock.c 2016-09-20 21:26:50 +0000
1599@@ -0,0 +1,36 @@
1600+/**
1601+ * Copyright © 2015 Canonical, Ltd.
1602+ *
1603+ * This program is free software: you can redistribute it and/or modify it under
1604+ * the terms of the GNU Lesser General Public License version 3, as published by
1605+ * the Free Software Foundation.
1606+ *
1607+ * This program is distributed in the hope that it will be useful, but WITHOUT
1608+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1609+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1610+ * Lesser General Public License for more details.
1611+ *
1612+ * You should have received a copy of the GNU Lesser General Public License
1613+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1614+ *
1615+ */
1616+
1617+#include <glib.h>
1618+#include <sys/apparmor.h>
1619+
1620+const char * aa_mock_gettask_profile = NULL;
1621+
1622+int aa_gettaskcon (pid_t pid, char ** profile, char ** mode)
1623+{
1624+ g_debug("Gettask Con '%s'", aa_mock_gettask_profile);
1625+
1626+ if (aa_mock_gettask_profile == NULL) {
1627+ return 1;
1628+ }
1629+
1630+ if (profile != NULL) {
1631+ *profile = g_strdup(aa_mock_gettask_profile);
1632+ }
1633+
1634+ return 0;
1635+}
1636
1637=== added file 'tests/apparmor-mock.h'
1638--- tests/apparmor-mock.h 1970-01-01 00:00:00 +0000
1639+++ tests/apparmor-mock.h 2016-09-20 21:26:50 +0000
1640@@ -0,0 +1,20 @@
1641+/**
1642+ * Copyright © 2015 Canonical, Ltd.
1643+ *
1644+ * This program is free software: you can redistribute it and/or modify it under
1645+ * the terms of the GNU Lesser General Public License version 3, as published by
1646+ * the Free Software Foundation.
1647+ *
1648+ * This program is distributed in the hope that it will be useful, but WITHOUT
1649+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1650+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1651+ * Lesser General Public License for more details.
1652+ *
1653+ * You should have received a copy of the GNU Lesser General Public License
1654+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1655+ *
1656+ */
1657+
1658+#pragma once
1659+
1660+extern const char * aa_mock_gettask_profile;
1661
1662=== modified file 'tests/click-data/manifests/com.test.good.manifest'
1663--- tests/click-data/manifests/com.test.good.manifest 2013-09-18 04:16:51 +0000
1664+++ tests/click-data/manifests/com.test.good.manifest 2016-09-20 21:26:50 +0000
1665@@ -3,7 +3,7 @@
1666 "name": "com.test.good",
1667 "hooks": {
1668 "app1": {
1669- "test": "test"
1670+ "desktop": "app1.desktop"
1671 }
1672 }
1673 }
1674
1675=== modified file 'tests/click-data/manifests/com.test.multiple.manifest'
1676--- tests/click-data/manifests/com.test.multiple.manifest 2013-09-26 20:30:45 +0000
1677+++ tests/click-data/manifests/com.test.multiple.manifest 2016-09-20 21:26:50 +0000
1678@@ -3,13 +3,13 @@
1679 "name": "com.test.good",
1680 "hooks": {
1681 "app-first": {
1682- "test": "test"
1683+ "desktop": "app-first.desktop"
1684 },
1685 "app-middle": {
1686- "test": "test"
1687+ "desktop": "app-middle.desktop"
1688 },
1689 "app-last": {
1690- "test": "test"
1691+ "desktop": "app-last.desktop"
1692 }
1693 }
1694 }
1695
1696=== modified file 'tests/dispatcher-test.cc'
1697--- tests/dispatcher-test.cc 2015-06-08 17:13:44 +0000
1698+++ tests/dispatcher-test.cc 2016-09-20 21:26:50 +0000
1699@@ -19,10 +19,13 @@
1700
1701 #include <gio/gio.h>
1702 #include <gtest/gtest.h>
1703+#include <libdbustest/dbus-test.h>
1704 #include "dispatcher.h"
1705 #include "ubuntu-app-launch-mock.h"
1706 #include "overlay-tracker-mock.h"
1707 #include "url-db.h"
1708+#include "scope-mock.h"
1709+#include "apparmor-mock.h"
1710
1711 class DispatcherTest : public ::testing::Test
1712 {
1713@@ -33,6 +36,7 @@
1714
1715 protected:
1716 OverlayTrackerMock tracker;
1717+ RuntimeMock scope_runtime;
1718 GDBusConnection * session = nullptr;
1719
1720 virtual void SetUp() {
1721@@ -66,6 +70,9 @@
1722 url_db_set_file_motification_time(db, "/testdir/intenter.url-dispatcher", &timestamp);
1723 url_db_insert_url(db, "/testdir/intenter.url-dispatcher", "intent", "my.android.package");
1724
1725+ url_db_set_file_motification_time(db, "/testdir/scoper.url-dispatcher", &timestamp);
1726+ url_db_insert_url(db, "/testdir/scoper.url-dispatcher", "scope", nullptr);
1727+
1728 sqlite3_close(db);
1729
1730 testbus = g_test_dbus_new(G_TEST_DBUS_NONE);
1731@@ -74,7 +81,7 @@
1732 session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
1733
1734 mainloop = g_main_loop_new(nullptr, FALSE);
1735- dispatcher_init(mainloop, reinterpret_cast<OverlayTracker *>(&tracker));
1736+ dispatcher_init(mainloop, reinterpret_cast<OverlayTracker *>(&tracker), reinterpret_cast<ScopeChecker *>(&scope_runtime));
1737
1738 return;
1739 }
1740@@ -90,6 +97,7 @@
1741 g_main_loop_unref(mainloop);
1742
1743 ubuntu_app_launch_mock_clear_last_app_id();
1744+ scope_runtime.clearExceptions();
1745
1746 /* let other threads settle */
1747 g_usleep(500000);
1748@@ -260,6 +268,42 @@
1749 return;
1750 }
1751
1752+DbusTestDbusMock *
1753+setupUpstartMock ()
1754+{
1755+ auto mock = dbus_test_dbus_mock_new("com.ubuntu.Upstart");
1756+ auto obj = dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", nullptr);
1757+
1758+ dbus_test_dbus_mock_object_add_method(mock, obj,
1759+ "GetJobByName",
1760+ G_VARIANT_TYPE_STRING,
1761+ G_VARIANT_TYPE_OBJECT_PATH, /* out */
1762+ "ret = dbus.ObjectPath('/job')", /* python */
1763+ nullptr); /* error */
1764+
1765+ auto jobobj = dbus_test_dbus_mock_get_object(mock, "/job", "com.ubuntu.Upstart0_6.Job", nullptr);
1766+
1767+ dbus_test_dbus_mock_object_add_method(mock, jobobj,
1768+ "GetInstanceByName",
1769+ G_VARIANT_TYPE_STRING,
1770+ G_VARIANT_TYPE_OBJECT_PATH, /* out */
1771+ "ret = dbus.ObjectPath('/instance')", /* python */
1772+ NULL); /* error */
1773+
1774+ auto instobj = dbus_test_dbus_mock_get_object(mock, "/instance", "com.ubuntu.Upstart0_6.Instance", NULL);
1775+
1776+ dbus_test_dbus_mock_object_add_property(mock, instobj,
1777+ "processes",
1778+ G_VARIANT_TYPE("a(si)"),
1779+ g_variant_new_parsed("[('main', 1234)]"),
1780+ NULL);
1781+
1782+ dbus_test_task_set_name(DBUS_TEST_TASK(mock), "Upstart");
1783+ dbus_test_task_run(DBUS_TEST_TASK(mock));
1784+
1785+ return mock;
1786+}
1787+
1788 TEST_F(DispatcherTest, OverlayTest)
1789 {
1790 EXPECT_TRUE(dispatcher_is_overlay("com.test.good_application_1.2.3"));
1791@@ -272,5 +316,44 @@
1792 EXPECT_EQ(getpid(), std::get<1>(tracker.addedOverlays[0]));
1793 EXPECT_EQ("overlay://ubuntu.com", std::get<2>(tracker.addedOverlays[0]));
1794
1795+ tracker.addedOverlays.clear();
1796+ aa_mock_gettask_profile = "simplescope.scopemaster_simplescope_1.2.3";
1797+
1798+ auto upstartMock = setupUpstartMock();
1799+
1800+ EXPECT_TRUE(dispatcher_send_to_overlay ("com.test.good_application_1.2.3", "overlay://ubuntu.com", session, g_dbus_connection_get_unique_name(session)));
1801+
1802+ ASSERT_EQ(1, tracker.addedOverlays.size());
1803+ EXPECT_EQ("com.test.good_application_1.2.3", std::get<0>(tracker.addedOverlays[0]));
1804+ EXPECT_EQ(1234, std::get<1>(tracker.addedOverlays[0]));
1805+ EXPECT_EQ("overlay://ubuntu.com", std::get<2>(tracker.addedOverlays[0]));
1806+
1807+ g_object_unref(upstartMock);
1808+
1809 return;
1810 }
1811+
1812+TEST_F(DispatcherTest, ScopeTest)
1813+{
1814+ gchar * out_appid = nullptr;
1815+
1816+ unity::scopes::NotFoundException scopeException("test", "badscope");
1817+ scope_runtime.addException("badscope.scopemaster_badscope", scopeException);
1818+ std::invalid_argument invalidException("confused");
1819+ scope_runtime.addException("confusedscope.scopemaster_confusedscope", invalidException);
1820+
1821+ /* Good sanity check */
1822+ dispatcher_url_to_appid("scope://simplescope.scopemaster_simplescope", &out_appid, nullptr);
1823+ EXPECT_STREQ("scoper", out_appid);
1824+ g_free(out_appid);
1825+
1826+ /* Bad scope */
1827+ dispatcher_url_to_appid("scope://badscope.scopemaster_badscope", &out_appid, nullptr);
1828+ EXPECT_STRNE("scoper", out_appid);
1829+ g_free(out_appid);
1830+
1831+ /* Confused scope */
1832+ dispatcher_url_to_appid("scope://confusedscope.scopemaster_confusedscope", &out_appid, nullptr);
1833+ EXPECT_STRNE("scoper", out_appid);
1834+ g_free(out_appid);
1835+}
1836
1837=== modified file 'tests/overlay-tracker-mock.h'
1838--- tests/overlay-tracker-mock.h 2015-05-19 20:24:47 +0000
1839+++ tests/overlay-tracker-mock.h 2016-09-20 21:26:50 +0000
1840@@ -22,9 +22,15 @@
1841 {
1842 public:
1843 std::vector<std::tuple<std::string, unsigned long, std::string>> addedOverlays;
1844+ std::vector<std::pair<unsigned long, std::string>> addedBadUrl;
1845
1846 bool addOverlay (const char * appid, unsigned long pid, const char * url) {
1847 addedOverlays.push_back(std::make_tuple(std::string(appid), pid, std::string(url)));
1848 return true;
1849 }
1850+
1851+ bool badUrl (unsigned long pid, const char * url) {
1852+ addedBadUrl.push_back(std::make_pair(pid, std::string(url)));
1853+ return true;
1854+ }
1855 };
1856
1857=== modified file 'tests/overlay-tracker-test.cpp'
1858--- tests/overlay-tracker-test.cpp 2015-05-19 20:24:47 +0000
1859+++ tests/overlay-tracker-test.cpp 2016-09-20 21:26:50 +0000
1860@@ -95,23 +95,43 @@
1861 }
1862 }
1863
1864-TEST_F(OverlayTrackerTest, UALSignalStop) {
1865- OverlayTrackerMir tracker;
1866+void
1867+ualStop (const char * helper_type, std::function<bool(OverlayTrackerMir *)> addFunc)
1868+{
1869+ auto tracker = new OverlayTrackerMir();
1870
1871 /* Call with the overlay before it is set */
1872- ubuntu_app_launch_mock_observer_helper_stop_func("app-id", "instance", "url-overlay", ubuntu_app_launch_mock_observer_helper_stop_user_data);
1873+ ubuntu_app_launch_mock_observer_helper_stop_func("app-id", "instance", helper_type, ubuntu_app_launch_mock_observer_helper_stop_user_data);
1874
1875- EXPECT_TRUE(tracker.addOverlay("app-id", 5, "http://no-name-yet.com"));
1876+ EXPECT_TRUE(addFunc(tracker));
1877
1878 mir_mock_last_released_session = nullptr;
1879- ubuntu_app_launch_mock_observer_helper_stop_func("app-id", "instance", "url-overlay", ubuntu_app_launch_mock_observer_helper_stop_user_data);
1880+ ubuntu_app_launch_mock_observer_helper_stop_func("app-id", "instance", helper_type, ubuntu_app_launch_mock_observer_helper_stop_user_data);
1881+
1882+ delete tracker;
1883+
1884 EXPECT_NE(nullptr, mir_mock_last_released_session);
1885 }
1886
1887-TEST_F(OverlayTrackerTest, MirSignalStop) {
1888- OverlayTrackerMir tracker;
1889-
1890- EXPECT_TRUE(tracker.addOverlay("app-id", 5, "http://no-name-yet.com"));
1891+TEST_F(OverlayTrackerTest, UALSignalStop) {
1892+ ualStop("url-overlay", [](OverlayTrackerMir * tracker) {
1893+ return tracker->addOverlay("app-id", 5, "http://no-name-yet.com");
1894+ });
1895+ ualStop("bad-url", [](OverlayTrackerMir * tracker) {
1896+ return tracker->badUrl(5, "http://no-name-yet.com");
1897+ });
1898+}
1899+
1900+void
1901+mirStop (const char * helper_type, const char * appid, std::function<bool(OverlayTrackerMir *)> addFunc)
1902+{
1903+ g_clear_pointer(&ubuntu_app_launch_mock_last_stop_helper, g_free);
1904+ g_clear_pointer(&ubuntu_app_launch_mock_last_stop_appid, g_free);
1905+ g_clear_pointer(&ubuntu_app_launch_mock_last_stop_instance, g_free);
1906+
1907+ auto tracker = new OverlayTrackerMir();
1908+
1909+ EXPECT_TRUE(addFunc(tracker));
1910
1911 /* Try a badie */
1912 mir_mock_last_trust_func((MirPromptSession *)1337, mir_prompt_session_state_stopped, mir_mock_last_trust_data);
1913@@ -119,9 +139,18 @@
1914 EXPECT_NE(nullptr, mir_mock_last_trust_func);
1915 mir_mock_last_trust_func(mir_mock_valid_trust_session, mir_prompt_session_state_stopped, mir_mock_last_trust_data);
1916
1917- pause(100);
1918+ delete tracker;
1919
1920- EXPECT_STREQ("url-overlay", ubuntu_app_launch_mock_last_stop_helper);
1921- EXPECT_STREQ("app-id", ubuntu_app_launch_mock_last_stop_appid);
1922+ EXPECT_STREQ(helper_type, ubuntu_app_launch_mock_last_stop_helper);
1923+ EXPECT_STREQ(appid, ubuntu_app_launch_mock_last_stop_appid);
1924 EXPECT_STREQ("instance", ubuntu_app_launch_mock_last_stop_instance);
1925 }
1926+
1927+TEST_F(OverlayTrackerTest, MirSignalStop) {
1928+ mirStop("url-overlay", "app-id", [](OverlayTrackerMir * tracker) {
1929+ return tracker->addOverlay("app-id", 5, "http://no-name-yet.com");
1930+ });
1931+ mirStop("bad-url", "url-dispatcher-bad-url-helper", [](OverlayTrackerMir * tracker) {
1932+ return tracker->badUrl(5, "http://no-name-yet.com");
1933+ });
1934+}
1935
1936=== added file 'tests/scope-mock.h'
1937--- tests/scope-mock.h 1970-01-01 00:00:00 +0000
1938+++ tests/scope-mock.h 2016-09-20 21:26:50 +0000
1939@@ -0,0 +1,95 @@
1940+/**
1941+ * Copyright © 2015 Canonical, Ltd.
1942+ *
1943+ * This program is free software: you can redistribute it and/or modify it under
1944+ * the terms of the GNU Lesser General Public License version 3, as published by
1945+ * the Free Software Foundation.
1946+ *
1947+ * This program is distributed in the hope that it will be useful, but WITHOUT
1948+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1949+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1950+ * Lesser General Public License for more details.
1951+ *
1952+ * You should have received a copy of the GNU Lesser General Public License
1953+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1954+ *
1955+ */
1956+
1957+#include <unity-scopes.h>
1958+#include <unity/scopes/testing/ScopeMetadataBuilder.h>
1959+
1960+#include "scope-checker-facade.h"
1961+
1962+class unity::scopes::internal::ScopeMetadataImpl {
1963+public:
1964+ ScopeMetadataImpl () { }
1965+ virtual ~ScopeMetadataImpl () {}
1966+
1967+};
1968+
1969+/********
1970+ TODO: Look at replacing this with: #include <unity/scopes/testing/MockRegistry.h>
1971+ *******/
1972+
1973+class RegistryMock : public virtual unity::scopes::Registry
1974+{
1975+ std::shared_ptr<std::map<std::string, std::exception>> scopeExceptions;
1976+
1977+public:
1978+ RegistryMock (std::shared_ptr<std::map<std::string, std::exception>> inexceptions)
1979+ : scopeExceptions(inexceptions)
1980+ {
1981+ }
1982+
1983+ unity::scopes::ScopeMetadata get_metadata(std::string const& scope_id) override {
1984+ std::cout << "Getting Metadata" << std::endl;
1985+ try {
1986+ auto exp = scopeExceptions->at(scope_id);
1987+ throw exp;
1988+ } catch (std::out_of_range e) {
1989+ unity::scopes::testing::ScopeMetadataBuilder builder;
1990+ builder.scope_id(scope_id);
1991+ std::shared_ptr<unity::scopes::Scope> foo((unity::scopes::Scope *)5, [](unity::scopes::Scope *) { return; });
1992+ builder.proxy(foo);
1993+ builder.display_name("foo");
1994+ builder.description("foo");
1995+ builder.author("foo");
1996+ return builder();
1997+ }
1998+ }
1999+
2000+ /* I hate C++ so much right now */
2001+ std::string endpoint() override { throw new std::invalid_argument("Not implemented"); }
2002+ std::string identity() override { throw new std::invalid_argument("Not implemented"); }
2003+ std::string target_category() override { throw new std::invalid_argument("Not implemented"); }
2004+ std::string to_string() override { throw new std::invalid_argument("Not implemented"); }
2005+ int64_t timeout() override { throw new std::invalid_argument("Not implemented"); }
2006+ unity::scopes::MetadataMap list() override { throw new std::invalid_argument("Not implemented"); }
2007+ unity::scopes::MetadataMap list_if(std::function<bool(unity::scopes::ScopeMetadata const& item)>) override { throw new std::invalid_argument("Not implemented"); }
2008+ bool is_scope_running(std::string const&) override { throw new std::invalid_argument("Not implemented"); }
2009+ core::ScopedConnection set_scope_state_callback(std::string const&, std::function<void(bool is_running)>) override { throw new std::invalid_argument("Not implemented"); }
2010+ core::ScopedConnection set_list_update_callback(std::function<void()>) override { throw new std::invalid_argument("Not implemented"); }
2011+};
2012+
2013+class RuntimeMock : public RuntimeFacade
2014+{
2015+ std::shared_ptr<std::map<std::string, std::exception>> scopeExceptions;
2016+
2017+public:
2018+ RuntimeMock() {
2019+ scopeExceptions = std::make_shared<std::map<std::string, std::exception>>();
2020+ }
2021+
2022+ unity::scopes::RegistryProxy registry () {
2023+ return std::make_shared<RegistryMock>(scopeExceptions);
2024+ }
2025+
2026+ void clearExceptions() {
2027+ scopeExceptions->clear();
2028+ }
2029+
2030+ void addException (std::string scopeid, std::exception exp) {
2031+ (*scopeExceptions)[scopeid] = exp;
2032+ }
2033+};
2034+
2035
2036=== modified file 'tests/service-test.cc'
2037--- tests/service-test.cc 2015-05-20 16:27:27 +0000
2038+++ tests/service-test.cc 2016-09-20 21:26:50 +0000
2039@@ -38,6 +38,7 @@
2040 virtual void SetUp() {
2041 g_setenv("UBUNTU_APP_LAUNCH_USE_SESSION", "1", TRUE);
2042 g_setenv("URL_DISPATCHER_DISABLE_RECOVERABLE_ERROR", "1", TRUE);
2043+ g_setenv("URL_DISPATCHER_DISABLE_SCOPE_CHECKING", "1", TRUE);
2044 g_setenv("XDG_DATA_DIRS", XDG_DATA_DIRS, TRUE);
2045 g_setenv("LD_PRELOAD", MIR_MOCK_PATH, TRUE);
2046
2047@@ -95,6 +96,10 @@
2048 }
2049
2050 virtual void TearDown() {
2051+ gchar * cmdline = g_strdup_printf("kill -TERM %d", dbus_test_process_get_pid(dispatcher));
2052+ g_spawn_command_line_sync(cmdline, nullptr, nullptr, nullptr, nullptr);
2053+ g_free(cmdline);
2054+
2055 g_clear_object(&dispatcher);
2056 g_clear_object(&mock);
2057 g_clear_object(&dashmock);
2058@@ -123,7 +128,7 @@
2059 GTimeVal time = {0, 0};
2060 time.tv_sec = 5;
2061 url_db_set_file_motification_time(db, "/unity8-dash.url-dispatcher", &time);
2062- url_db_insert_url(db, "/unity8-dash.url-dispatcher", "scope", nullptr);
2063+ url_db_insert_url(db, "/unity8-dash.url-dispatcher", "scopeish", nullptr);
2064 sqlite3_close(db);
2065 }
2066
2067@@ -271,7 +276,7 @@
2068 GMainLoop * main = g_main_loop_new(nullptr, FALSE);
2069
2070 /* Send an invalid URL */
2071- url_dispatch_send("scope://foo-bar", simple_cb, main);
2072+ url_dispatch_send("scopeish://foo-bar", simple_cb, main);
2073
2074 /* Give it some time to send and reply */
2075 g_main_loop_run(main);
2076@@ -288,7 +293,7 @@
2077 calls = dbus_test_dbus_mock_object_get_method_calls(dashmock, fdoobj, "Open", &callslen, nullptr);
2078
2079 EXPECT_EQ(1, callslen);
2080- EXPECT_TRUE(g_variant_equal(calls[0].params, g_variant_new_parsed("(['scope://foo-bar'], @a{sv} {})")));
2081+ EXPECT_TRUE(g_variant_equal(calls[0].params, g_variant_new_parsed("(['scopeish://foo-bar'], @a{sv} {})")));
2082
2083 EXPECT_EQ(1, focus_count);
2084
2085
2086=== modified file 'tests/test-config.h.in'
2087--- tests/test-config.h.in 2015-06-08 16:39:15 +0000
2088+++ tests/test-config.h.in 2016-09-20 21:26:50 +0000
2089@@ -11,6 +11,6 @@
2090 #define UPDATE_DIRECTORY_VARIED "@CMAKE_CURRENT_SOURCE_DIR@/test-urls-varied"
2091 #define UPDATE_DIRECTORY_INTENT "@CMAKE_CURRENT_SOURCE_DIR@/test-urls-intent"
2092 #define OVERLAY_TEST_DIR "@CMAKE_CURRENT_SOURCE_DIR@/overlay-dir"
2093-#define EXEC_TOOL "@CMAKE_BINARY_DIR@/service/exec-tool"
2094+#define EXEC_TOOL "@CMAKE_BINARY_DIR@/service/url-overlay/exec-tool"
2095 #define MIR_MOCK_PATH "@CMAKE_CURRENT_BINARY_DIR@/libmir-mock.so"
2096 #define CLICK_DATA_DIR "@CMAKE_CURRENT_SOURCE_DIR@/click-data"
2097
2098=== added directory 'tests/ual-link-farm'
2099=== added file 'tests/ual-link-farm/com.test.good_app1_1.2.3.desktop'
2100--- tests/ual-link-farm/com.test.good_app1_1.2.3.desktop 1970-01-01 00:00:00 +0000
2101+++ tests/ual-link-farm/com.test.good_app1_1.2.3.desktop 2016-09-20 21:26:50 +0000
2102@@ -0,0 +1,1 @@
2103+Needs to exist
2104
2105=== added file 'tests/ual-link-farm/com.test.multiple_app-first_1.2.3.desktop'
2106--- tests/ual-link-farm/com.test.multiple_app-first_1.2.3.desktop 1970-01-01 00:00:00 +0000
2107+++ tests/ual-link-farm/com.test.multiple_app-first_1.2.3.desktop 2016-09-20 21:26:50 +0000
2108@@ -0,0 +1,1 @@
2109+Needs to exist
2110
2111=== added directory 'tests/xdg-cache'
2112=== added directory 'tests/xdg-cache/libertine-container'
2113=== added directory 'tests/xdg-cache/libertine-container/container-id'
2114=== added directory 'tests/xdg-cache/libertine-container/container-id/rootfs'
2115=== added directory 'tests/xdg-cache/libertine-container/container-id/rootfs/usr'
2116=== added directory 'tests/xdg-cache/libertine-container/container-id/rootfs/usr/share'
2117=== added directory 'tests/xdg-cache/libertine-container/container-id/rootfs/usr/share/applications'
2118=== added file 'tests/xdg-cache/libertine-container/container-id/rootfs/usr/share/applications/org.canonical.app1.desktop'
2119--- tests/xdg-cache/libertine-container/container-id/rootfs/usr/share/applications/org.canonical.app1.desktop 1970-01-01 00:00:00 +0000
2120+++ tests/xdg-cache/libertine-container/container-id/rootfs/usr/share/applications/org.canonical.app1.desktop 2016-09-20 21:26:50 +0000
2121@@ -0,0 +1,4 @@
2122+[Desktop File]
2123+Name=App1
2124+Exec=app1
2125+Icon=app1.png
2126
2127=== modified file 'tests/xdg-data/applications/foo-bar.desktop'
2128--- tests/xdg-data/applications/foo-bar.desktop 2014-09-17 22:12:21 +0000
2129+++ tests/xdg-data/applications/foo-bar.desktop 2016-09-20 21:26:50 +0000
2130@@ -2,3 +2,4 @@
2131 Name=Foo Bar
2132 Exec=foo-bar
2133 Type=Application
2134+Icon=foo-bar.png

Subscribers

People subscribed via source and target branches

to all changes: