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

Proposed by Jonas G. Drange
Status: Merged
Approved by: Ken VanDine
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
Ken VanDine Approve
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

add system to shortcut

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1597. By Jonas G. Drange

log

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1598. By Jonas G. Drange

make a qsettings instance for each call due to threading

1599. By Jonas G. Drange

fix typo

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1600. By Jonas G. Drange

investigate crash on the phone

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1601. By Jonas G. Drange

wording, refactor

1602. By Jonas G. Drange

  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

note about removing duplicate code

1604. By Jonas G. Drange

wording, remove extra whitespace

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1605. By Jonas G. Drange

remove erroneous /

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1606. By Jonas G. Drange

remove debug

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) :
review: Needs Information
1607. By Jonas G. Drange

improve clarity of comment

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks good and works well

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

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