Merge lp:~jonas-drange/ubuntu-system-settings/lp1533835 into lp:ubuntu-system-settings

Proposed by Jonas G. Drange on 2016-02-10
Status: Merged
Approved by: Ken VanDine on 2016-02-18
Approved revision: 1607
Merged at revision: 1596
Proposed branch: lp:~jonas-drange/ubuntu-system-settings/lp1533835
Merge into: lp:ubuntu-system-settings
Diff against target: 247 lines (+144/-2)
7 files modified
plugins/security-privacy/AppAccess.qml (+24/-0)
plugins/security-privacy/PageComponent.qml (+36/-0)
src/CMakeLists.txt (+1/-0)
src/qml/MainWindow.qml (+2/-1)
src/url-map.ini (+11/-0)
src/utils.cpp (+67/-1)
src/utils.h (+3/-0)
To merge this branch: bzr merge lp:~jonas-drange/ubuntu-system-settings/lp1533835
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing on 2016-02-18
Ken VanDine 2016-02-10 Approve on 2016-02-18
Review via email: mp+285603@code.launchpad.net

Commit Message

* Define a map used for mapping short, panel-agnostic URLs and expose translation functionality to both QML and c++.

[Ugo Riboni]
 * Allow url-dispatcher access to App Permissions service pages

To post a comment you must log in.
1596. By Jonas G. Drange on 2016-02-10

add system to shortcut

1597. By Jonas G. Drange on 2016-02-11

log

1598. By Jonas G. Drange on 2016-02-12

make a qsettings instance for each call due to threading

1599. By Jonas G. Drange on 2016-02-12

fix typo

1600. By Jonas G. Drange on 2016-02-12

investigate crash on the phone

1601. By Jonas G. Drange on 2016-02-15

wording, refactor

1602. By Jonas G. Drange on 2016-02-15

  Ugo Riboni 2015-12-08 Ensure that we are not pushing the subpages until the PageComponent itself has been pushed

1603. By Jonas G. Drange on 2016-02-15

note about removing duplicate code

1604. By Jonas G. Drange on 2016-02-15

wording, remove extra whitespace

1605. By Jonas G. Drange on 2016-02-16

remove erroneous /

1606. By Jonas G. Drange on 2016-02-16

remove debug

Ken VanDine (ken-vandine) :
review: Needs Information
1607. By Jonas G. Drange on 2016-02-18

improve clarity of comment

Ken VanDine (ken-vandine) wrote :

Looks good and works well

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/security-privacy/AppAccess.qml'
2--- plugins/security-privacy/AppAccess.qml 2015-09-18 14:18:11 +0000
3+++ plugins/security-privacy/AppAccess.qml 2016-02-18 15:42:29 +0000
4@@ -27,6 +27,21 @@
5 id: root
6 title: i18n.tr("App permissions")
7
8+ function openService(service) {
9+ for (var i = 0; i < appsModel.count; i++) {
10+ var item = appsModel.get(i)
11+ if (item.service === service) {
12+ var model = trustStoreModelComponent.createObject(null, { serviceName: item.trustStoreService })
13+ pageStack.push(Qt.resolvedUrl("AppAccessControl.qml"), {
14+ "title": i18n.tr(item.name),
15+ "caption": i18n.tr(item.caption),
16+ "model": model
17+ })
18+ return;
19+ }
20+ }
21+ }
22+
23 Flickable {
24 anchors.fill: parent
25 contentHeight: contentItem.childrenRect.height
26@@ -52,16 +67,19 @@
27 name: QT_TR_NOOP("Camera")
28 caption: QT_TR_NOOP("Apps that have requested access to your camera")
29 trustStoreService: "CameraService"
30+ service: "camera"
31 }
32 ListElement {
33 name: QT_TR_NOOP("Location")
34 caption: QT_TR_NOOP("Apps that have requested access to your location")
35 trustStoreService: "UbuntuLocationService"
36+ service: "location"
37 }
38 ListElement {
39 name: QT_TR_NOOP("Microphone")
40 caption: QT_TR_NOOP("Apps that have requested access to your microphone")
41 trustStoreService: "PulseAudio"
42+ service: "microphone"
43 }
44 }
45
46@@ -113,4 +131,10 @@
47 }
48 }
49 }
50+
51+ Component {
52+ id: trustStoreModelComponent
53+ TrustStoreModel {}
54+ }
55+
56 }
57
58=== modified file 'plugins/security-privacy/PageComponent.qml'
59--- plugins/security-privacy/PageComponent.qml 2015-10-16 13:42:50 +0000
60+++ plugins/security-privacy/PageComponent.qml 2016-02-18 15:42:29 +0000
61@@ -53,6 +53,42 @@
62 });
63 return t;
64 }
65+ property var pluginOptions
66+ Connections {
67+ target: pageStack
68+ onCurrentPageChanged: {
69+ // If we are called with subpage=foo, push foo on the stack.
70+ //
71+ // We need to wait until the PageComponent has been pushed to the stack
72+ // before pushing the subpages, otherwise they will be pushed below the
73+ // PageComponent.
74+ if (pageStack.currentPage === root) {
75+ if (pluginOptions && pluginOptions['subpage']) {
76+ switch (pluginOptions['subpage']) {
77+ case 'location':
78+ pageStack.push(Qt.resolvedUrl("Location.qml"));
79+ break;
80+ case 'permissions':
81+ var page = pageStack.push(Qt.resolvedUrl("AppAccess.qml"), {pluginManager: pluginManager})
82+ if (pluginOptions['service']) {
83+ page.openService(pluginOptions['service'])
84+ }
85+ break;
86+ }
87+ } else if (pluginOptions && pluginOptions['service']) {
88+ // This whole else if branch will be removed once the
89+ // camera app asks for [1] as described in lp:1545733.
90+ // [1] settings:///system/permissions?service=camera
91+ var page = pageStack.push(Qt.resolvedUrl("AppAccess.qml"), {pluginManager: pluginManager})
92+ page.openService(pluginOptions['service'])
93+ }
94+
95+ // Once done, disable this Connections, so that if the user navigates
96+ // back to the root we won't push the subpages again
97+ target = null
98+ }
99+ }
100+ }
101
102 UbuntuDiagnostics {
103 id: diagnosticsWidget
104
105=== modified file 'src/CMakeLists.txt'
106--- src/CMakeLists.txt 2014-10-31 14:53:32 +0000
107+++ src/CMakeLists.txt 2016-02-18 15:42:29 +0000
108@@ -43,3 +43,4 @@
109 set_target_properties(uss-sessionservice PROPERTIES VERSION 0.0 SOVERSION 0.0)
110 install(TARGETS uss-accountsservice LIBRARY DESTINATION ${PLUGIN_MODULE_DIR} NAMELINK_SKIP)
111 install(TARGETS uss-sessionservice LIBRARY DESTINATION ${PLUGIN_MODULE_DIR} NAMELINK_SKIP)
112+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/url-map.ini DESTINATION ${PLUGIN_MANIFEST_DIR})
113
114=== modified file 'src/qml/MainWindow.qml'
115--- src/qml/MainWindow.qml 2016-02-04 16:26:15 +0000
116+++ src/qml/MainWindow.qml 2016-02-18 15:42:29 +0000
117@@ -73,7 +73,8 @@
118 Connections {
119 target: UriHandler
120 onOpened: {
121- var url = String(uris)
122+ var url = String(uris);
123+ url = Utilities.mapUrl(url);
124 var panelAndOptions = url.replace("settings:///system/", "")
125 var optionIndex = panelAndOptions.indexOf("?")
126 var panel = optionIndex > -1 ?
127
128=== added file 'src/url-map.ini'
129--- src/url-map.ini 1970-01-01 00:00:00 +0000
130+++ src/url-map.ini 2016-02-18 15:42:29 +0000
131@@ -0,0 +1,11 @@
132+; A list of sources mapped to destinations. A destination is some
133+; URL that a plugin is expected to handle.
134+;
135+; For the sake of simplicity, the first non-empty path component
136+; that is not “system” should be used as sources. I.e., given the URL
137+; “settings:///system/location” System Settings should check this
138+; file for the key “sources/location”.
139+
140+[sources]
141+location=settings:///system/security-privacy?subpage=location
142+permissions=settings:///system/security-privacy?subpage=permissions
143
144=== modified file 'src/utils.cpp'
145--- src/utils.cpp 2014-10-24 20:04:30 +0000
146+++ src/utils.cpp 2016-02-18 15:42:29 +0000
147@@ -36,7 +36,7 @@
148 for (int i = 1; i < arguments.count(); i++) {
149 const QString &argument = arguments.at(i);
150 if (argument.startsWith("settings://")) {
151- QUrl urlArgument(argument);
152+ QUrl urlArgument(Utilities::getDestinationUrl(argument));
153 /* Find out which plugin is required. If the first component of the
154 * path is "system", just skip it. */
155 QStringList pathComponents =
156@@ -76,4 +76,70 @@
157 return q_formatted_size;
158 }
159
160+/*
161+ * This function makes getDestinationUrl invokable from QML.
162+ */
163+QString Utilities::mapUrl(const QString &source)
164+{
165+ return Utilities::getDestinationUrl(source);
166+}
167+
168+/*
169+ * Returns a destination for the given source if the source has an entry
170+ * in url-map.ini (based on the first path component, excluding “system”).
171+ * If there were any query items on the source, these are appended to the
172+ * destination.
173+
174+ * If the source had no entry, it's returned unchanged.
175+ */
176+QString Utilities::getDestinationUrl(const QString &source)
177+{
178+ // This method will be called from multiple threads, and QSettings
179+ // is reentrant, meaning each call to this function require its own
180+ // settings instance.
181+ QSettings map(
182+ QString("%1/%2").arg(PLUGIN_MANIFEST_DIR).arg("url-map.ini"),
183+ QSettings::IniFormat
184+ );
185+ map.sync();
186+
187+ // If reading the map failed, return the source unchanged.
188+ if (map.status() != QSettings::NoError) {
189+ qWarning() << "reading url map failed: " << map.status();
190+ return source;
191+ }
192+
193+ QUrl sourceUrl(source);
194+ QStringList pathComponents =
195+ sourceUrl.path().split('/', QString::SkipEmptyParts);
196+
197+ int pluginIndex = 0;
198+ if (pathComponents.value(pluginIndex, "") == "system")
199+ pluginIndex++;
200+ QString key = pathComponents.value(pluginIndex, QString());
201+
202+ map.beginGroup("sources");
203+ if (map.contains(key)) {
204+ QString destination = map.value(key, QVariant()).toString();
205+
206+ // Copy any query items from the source to the destination
207+ if (sourceUrl.hasQuery()) {
208+ QUrl destinationUrl = QUrl(destination);
209+ QUrlQuery sQ(sourceUrl);
210+ QUrlQuery dQ(destinationUrl);
211+
212+ // Insert all query items from source query to destination query.
213+ for (int i = 0; i < sQ.queryItems().size(); ++i) {
214+ const QPair<QString, QString> a(sQ.queryItems().at(i));
215+ dQ.addQueryItem(a.first, a.second);
216+ }
217+
218+ destinationUrl.setQuery(dQ);
219+ destination = destinationUrl.toString();
220+ }
221+ return destination;
222+ }
223+ return source;
224+}
225+
226 } // namespace
227
228=== modified file 'src/utils.h'
229--- src/utils.h 2014-10-24 20:04:30 +0000
230+++ src/utils.h 2016-02-18 15:42:29 +0000
231@@ -21,6 +21,7 @@
232 #ifndef SYSTEM_SETTINGS_UTILS_H
233 #define SYSTEM_SETTINGS_UTILS_H
234
235+#include <QSettings>
236 #include <QStringList>
237 #include <QVariantMap>
238
239@@ -35,6 +36,8 @@
240 public:
241 explicit Utilities(QObject *parent = 0);
242 Q_INVOKABLE QString formatSize(quint64) const;
243+ Q_INVOKABLE QString mapUrl(const QString &source);
244+ static QString getDestinationUrl(const QString &source);
245 };
246
247 } // namespace

Subscribers

People subscribed via source and target branches