Merge lp:~jonas-drange/ubuntu-system-settings/allow-insecure-hotspot into lp:ubuntu-system-settings

Proposed by Jonas G. Drange
Status: Merged
Approved by: Ken VanDine
Approved revision: 1527
Merged at revision: 1526
Proposed branch: lp:~jonas-drange/ubuntu-system-settings/allow-insecure-hotspot
Merge into: lp:ubuntu-system-settings
Diff against target: 846 lines (+421/-106)
14 files modified
debian/control (+2/-2)
plugins/hotspot/CMakeLists.txt (+2/-0)
plugins/hotspot/HotspotSetup.qml (+95/-42)
plugins/hotspot/PageComponent.qml (+3/-10)
plugins/hotspot/hotspot.settings (+2/-1)
plugins/hotspot/plugin/CMakeLists.txt (+8/-0)
plugins/hotspot/plugin/hotspot-plugin.cpp (+88/-0)
plugins/hotspot/plugin/hotspot-plugin.h (+39/-0)
tests/autopilot/ubuntu_system_settings/__init__.py (+15/-0)
tests/autopilot/ubuntu_system_settings/tests/__init__.py (+70/-41)
tests/autopilot/ubuntu_system_settings/tests/connectivity.py (+12/-0)
tests/autopilot/ubuntu_system_settings/tests/systemimage.py (+48/-0)
tests/autopilot/ubuntu_system_settings/tests/test_hotspot.py (+22/-9)
tests/autopilot/ubuntu_system_settings/tests/test_plugins.py (+15/-1)
To merge this branch: bzr merge lp:~jonas-drange/ubuntu-system-settings/allow-insecure-hotspot
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Ken VanDine Approve
Matthew Paul Thomas (community) Needs Fixing
Pete Woods Pending
Review via email: mp+269671@code.launchpad.net

Commit message

[hotspot] allow insecure hotspot, hide hotspot for mako, make autopilot tests run on mako, and change packaging so we get a newer Connectivity API (provided by indicator-network).

Description of the change

* Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
Yes
 * Did you build your software in a clean sbuild/pbuilder chroot or ppa?
Yes
 * Did you build your software in a clean sbuild/pbuilder armhf chroot or ppa?
Yes
 * Has your component "TestPlan” been executed successfully on emulator, N4?
Yes
 * Has a 5 minute exploratory testing run been executed on N4?
N/A
 * If you changed the packaging (debian), did you subscribe a core-dev to this MP?
Yes, and Ken VanDine is subscribed.
 * If you changed the UI, did you subscribe the design-reviewers to this MP?
Yes (mpt)
 * What components might get impacted by your changes?
Hotspot
 * Have you requested review by the teams of these owning components?
N/A

To post a comment you must log in.
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)
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) wrote :

The latest CI run did have a hotspot related failure:
ubuntu_system_settings.tests.test_hotspot.HotspotSetupTestCase.test_insecure_setup

The other failures look unrelated

Revision history for this message
Matthew Paul Thomas (mpt) wrote :

Thanks for this refinement!

review: Needs Fixing
Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

> The latest CI run did have a hotspot related failure:
> ubuntu_system_settings.tests.test_hotspot.HotspotSetupTestCase.test_insecure_s
> etup
>
> The other failures look unrelated
Right, we need a newer Connectivity API for insecure setup to work, so this is expected. I'll bump deps to make the CI fail completely.

Revision history for this message
Jonas G. Drange (jonas-drange) wrote :

On 3 September 2015 at 13:18, Matthew Paul Thomas <email address hidden> wrote:

> Review: Needs Fixing
>
> ​… ​
> If you check the checkbox, the password field should be focused
> automatically.
>

​Not sure I understand your comment, but I've added a note about this being
a workaround with reference to lp:1415023

​​

> How is settingsValid() ever true when passwordRequiredSwitch is unchecked?
>

settingsValid tests if 1) ssid is a string (not "") and 2) if the
passwordRequired checkbox is checked, it sees if the password length is >=
8.

Could you file a bug about hexadecimal passwords so we can have a
discussion about it? I want to make sure NetworkManager/wpa_supplicant can
handle it before implementing it. Thanks!

As for the rest, I would love another peek at the updated diff (r1519).

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

create plugin for hotspot

1521. By Jonas G. Drange

refactor test classes for re-use, refactor dynamic visibility logic

1522. By Jonas G. Drange

remove mako exceptions in setup code now that the plugin is hidden altogether

1523. By Jonas G. Drange

remove visibility exception in test objects, prune diff

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

I, very informally, measured the start up time of System Settings on mako before and after adding the dynamic visibility of the hotspot entry.

Static hotspot visibility, start up time (in seconds):
4.8
4.7
4.7
4.6
4.6
5.1

Dynamic hotspot visibility, start up time (in seconds):
4.8
4.9
5.1
5.1
4.9
4.7

A 0.1 to 0.3 seconds penalty was added.

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) wrote :

See inline comment

review: Needs Fixing
1524. By Jonas G. Drange

unnecessary comment

1525. By Jonas G. Drange

make mako comment clearer

1526. By Jonas G. Drange

remove qstringlist and qdebug include

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) wrote :

There are 2 places where the strings don't match the design (not necessarily part of this MR, but lets fix it here)

HotSpotSetup.qml
- i18n.tr("Change hotspot setup") : i18n.tr("Setup hotspot")
+ i18n.tr("Change Hotspot Setup") : i18n.tr("Set Up Hotspot")

PageComponent.qml
- i18n.tr("Change password/setup…") : i18n.tr("Set up hotspot…")
+ i18n.tr("Change Password/Setup…") : i18n.tr("Set Up Hotspot…")

review: Needs Fixing
1527. By Jonas G. Drange

be consistent in casing and setup vs set up

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

Thanks, looks good!

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 'debian/control'
2--- debian/control 2015-08-24 07:50:13 +0000
3+++ debian/control 2015-09-10 15:34:03 +0000
4@@ -23,7 +23,7 @@
5 libunity-api-dev,
6 libupower-glib-dev,
7 pkg-config,
8- qml-module-ubuntu-connectivity (>= 0.5.3),
9+ qml-module-ubuntu-connectivity (>= 0.5.4),
10 qt5-default,
11 qtbase5-dev,
12 qtdeclarative5-dev,
13@@ -71,7 +71,7 @@
14 powerd (>= 0.15) | gnome-settings-daemon,
15 qmenumodel-qml,
16 qml-module-qt-labs-folderlistmodel,
17- qml-module-ubuntu-connectivity (>= 0.5.3),
18+ qml-module-ubuntu-connectivity (>= 0.5.4),
19 qml-module-qtmultimedia | qml-module-qtmultimedia-gles,
20 qtdeclarative5-gsettings1.0 (>=0.1+14.10.20140801.1),
21 qtdeclarative5-ofono0.2 (>=0.70~),
22
23=== modified file 'plugins/hotspot/CMakeLists.txt'
24--- plugins/hotspot/CMakeLists.txt 2015-08-12 15:06:37 +0000
25+++ plugins/hotspot/CMakeLists.txt 2015-09-10 15:34:03 +0000
26@@ -1,3 +1,5 @@
27+add_subdirectory(plugin)
28+
29 set(QML_SOURCES
30 Common.qml
31 HotspotSetup.qml
32
33=== modified file 'plugins/hotspot/HotspotSetup.qml'
34--- plugins/hotspot/HotspotSetup.qml 2015-08-17 15:35:08 +0000
35+++ plugins/hotspot/HotspotSetup.qml 2015-09-10 15:34:03 +0000
36@@ -43,11 +43,21 @@
37 anchorToKeyboard: true
38
39 function settingsValid() {
40- return ssidField.text != "" && passwordField.length >= 8;
41+ var ssidValid = ssidField.text !== "";
42+ var passwordValid = passwordRequiredToggle.checked ?
43+ passwordField.length >= 8 : true;
44+ return ssidValid && passwordValid;
45+ }
46+
47+ function updateHotspotSettings () {
48+ Connectivity.hotspotSsid = ssidField.text;
49+ Connectivity.hotspotPassword = passwordField.text;
50+ Connectivity.hotspotAuth = passwordRequiredToggle.checked ?
51+ "wpa-psk" : "none";
52 }
53
54 title: stored ?
55- i18n.tr("Change hotspot setup") : i18n.tr("Setup hotspot")
56+ i18n.tr("Change Hotspot Setup") : i18n.tr("Set Up Hotspot")
57 text: feedback.enabled ? feedback.text : "";
58
59 Common {
60@@ -70,7 +80,11 @@
61 enabled: false
62 }
63 PropertyChanges {
64- target: passwordLabel
65+ target: passwordRequired
66+ enabled: false
67+ }
68+ PropertyChanges {
69+ target: passwordRequiredLabel
70 opacity: 0.5
71 }
72 PropertyChanges {
73@@ -117,14 +131,18 @@
74 opacity: 0.5
75 }
76 PropertyChanges {
77+ target: passwordRequired
78+ enabled: false
79+ }
80+ PropertyChanges {
81+ target: passwordRequiredLabel
82+ opacity: 0.5
83+ }
84+ PropertyChanges {
85 target: ssidField
86 enabled: false
87 }
88 PropertyChanges {
89- target: passwordLabel
90- opacity: 0.5
91- }
92- PropertyChanges {
93 target: passwordField
94 enabled: false
95 }
96@@ -132,10 +150,6 @@
97 target: confirmButton
98 enabled: false
99 }
100- PropertyChanges {
101- target: enableWifiCaption
102- visible: false
103- }
104 }
105 ]
106
107@@ -157,8 +171,8 @@
108
109 Label {
110 id: ssidLabel
111- text: i18n.tr("Hotspot name")
112- fontSize: "medium"
113+ text: hotspotSetupDialog.stored ? i18n.tr("Hotspot name") :
114+ i18n.tr("Choose a name")
115 font.bold: true
116 color: Theme.palette.selected.backgroundText
117 elide: Text.ElideRight
118@@ -173,43 +187,78 @@
119 width: parent.width
120 }
121
122- Label {
123- id: passwordLabel
124- // TRANSLATORS: “Password (optional)” is hidden.
125- text: showAllUI ? i18n.tr("Password (optional)") :
126- i18n.tr("Key (must be 8 characters or longer)")
127- fontSize: "medium"
128- font.bold: true
129- color: Theme.palette.selected.backgroundText
130- wrapMode: Text.WordWrap
131- width: parent.width
132- }
133-
134- Label {
135- visible: showAllUI
136- // TRANSLATORS: This string is hidden.
137- text: i18n.tr("If you do not enter a password, the hotspot will be insecure.")
138+ ListItem.Empty {
139+ id: passwordRequired
140+ onClicked: passwordRequiredToggle.trigger()
141+
142+ CheckBox {
143+ id: passwordRequiredToggle
144+ objectName: "passwordRequiredToggle"
145+ checked: Connectivity.hotspotAuth === "wpa-psk"
146+ anchors {
147+ left: parent.left
148+ verticalCenter: parent.verticalCenter
149+ }
150+ // FIXME: Workaround for lp:1415023
151+ activeFocusOnPress: false
152+ }
153+
154+ Label {
155+ id: passwordRequiredLabel
156+ anchors {
157+ left: passwordRequiredToggle.right
158+ leftMargin: units.gu(1)
159+ right: parent.right
160+ verticalCenter: parent.verticalCenter
161+ }
162+
163+ // FIXME: Workaround for label not wrapping (lp:1442851)
164+ wrapMode: Text.Wrap
165+ text: i18n.tr("Require a password (recommended):")
166+ }
167 }
168
169 TextField {
170 id: passwordField
171 objectName: "passwordField"
172+ enabled: passwordRequiredToggle.checked
173 text: Connectivity.hotspotPassword
174- echoMode: passwordVisibleSwitch.checked ?
175+ echoMode: passwordVisibleToggle.checked ?
176 TextInput.Normal : TextInput.Password
177 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
178 width: parent.width
179 }
180
181- ListItem.Standard {
182- // TRANSLATORS: “Show password” is hidden.
183- text: showAllUI ? i18n.tr("Show password") : i18n.tr("Show key")
184+ ListItem.Empty {
185 id: passwordVisible
186- onClicked: passwordVisibleSwitch.trigger()
187- control: Switch {
188- id: passwordVisibleSwitch
189+ enabled: passwordRequiredToggle.checked
190+ onClicked: passwordVisibleToggle.trigger()
191+
192+ CheckBox {
193+ id: passwordVisibleToggle
194+ enabled: parent.enabled
195+ anchors {
196+ left: parent.left
197+ verticalCenter: parent.verticalCenter
198+ }
199+
200+ // FIXME: Workaround for lp:1415023
201 activeFocusOnPress: false
202 }
203+
204+ Label {
205+ id: passwordVisibleLabel
206+
207+ /* FIXME: use enabled when lp:1491802 is fixed, or use
208+ CheckBox.text once lp:1323238 is fixed. */
209+ opacity: passwordRequiredToggle.checked ? 1 : 0.5
210+ anchors {
211+ left: passwordVisibleToggle.right
212+ leftMargin: units.gu(1)
213+ verticalCenter: parent.verticalCenter
214+ }
215+ text: i18n.tr("Show password")
216+ }
217 }
218
219 ListItem.Caption {
220@@ -218,8 +267,10 @@
221 left: parent.left
222 right: parent.right
223 }
224- text: i18n.tr("In order to create a hotspot, you need to turn Wi-Fi on.")
225- visible: !Connectivity.wifiEnabled && !hotspotSetupDialog.stored
226+ text: i18n.tr("Starting the hotspot will turn on Wi-Fi.")
227+ visible: !Connectivity.wifiEnabled &&
228+ !hotspotSetupDialog.stored &&
229+ hotspotSetupDialog.state !== "SUCCEEDED"
230 }
231
232 Row {
233@@ -235,6 +286,8 @@
234 id: cancelButton
235 width: (parent.width / 2) - units.gu(1)
236 text: i18n.tr("Cancel")
237+
238+ // FIXME: Workaround for lp:1415023
239 activeFocusOnPress: false
240 onClicked: PopupUtils.close(hotspotSetupDialog)
241 }
242@@ -246,6 +299,8 @@
243 text: hotspotSetupDialog.stored ? i18n.tr("Change") :
244 i18n.tr("Start")
245 enabled: settingsValid()
246+
247+ // FIXME: Workaround for lp:1415023
248 activeFocusOnPress: false
249 onClicked: {
250 if (!Connectivity.wifiEnabled &&
251@@ -309,8 +364,7 @@
252 }
253 }
254
255- Connectivity.hotspotSsid = ssidField.text;
256- Connectivity.hotspotPassword = passwordField.text;
257+ hotspotSetupDialog.updateHotspotSettings();
258 Connectivity.hotspotEnabledUpdated.connect(hotspotEnabledHandler);
259 Connectivity.hotspotEnabled = true;
260 }
261@@ -338,8 +392,7 @@
262 }
263 }
264
265- Connectivity.hotspotSsid = ssidField.text;
266- Connectivity.hotspotPassword = passwordField.text;
267+ hotspotSetupDialog.updateHotspotSettings();
268
269 if (Connectivity.hotspotEnabled) {
270 hotspotSetupDialog.state = "STARTING";
271
272=== modified file 'plugins/hotspot/PageComponent.qml'
273--- plugins/hotspot/PageComponent.qml 2015-08-17 21:41:30 +0000
274+++ plugins/hotspot/PageComponent.qml 2015-09-10 15:34:03 +0000
275@@ -25,11 +25,6 @@
276 import Ubuntu.Components.Popups 0.1
277 import Ubuntu.Connectivity 1.0
278
279-/* This is a temporary solution to the issue of Hotspots failing on mako. If
280-the device is mako, we hide the hotspot entry. Will be removed once lp:1434591
281-has been resolved. */
282-import Ubuntu.SystemSettings.Update 1.0
283-
284 ItemPage {
285
286 id: root
287@@ -40,10 +35,8 @@
288 State {
289 name: "disabled"
290 // Undefined WifiEnabled means Connectivity is unavailable.
291- // Disable for mako (see lp:1434591).
292- when: (typeof Connectivity.wifiEnabled === "undefined" ||
293- UpdateManager.deviceName === "mako") ||
294- Connectivity.FlightMode
295+ when: typeof Connectivity.wifiEnabled === "undefined" ||
296+ Connectivity.FlightMode
297 PropertyChanges {
298 target: hotspotItem
299 enabled: false
300@@ -124,7 +117,7 @@
301 anchors.horizontalCenter: parent.horizontalCenter
302 width: parent.width - units.gu(4)
303 text: Connectivity.hotspotStored ?
304- i18n.tr("Change password/setup…") : i18n.tr("Set up hotspot…")
305+ i18n.tr("Change Password/Setup…") : i18n.tr("Set Up Hotspot…")
306 onClicked: {
307 setup.setSource(Qt.resolvedUrl("HotspotSetup.qml"));
308 PopupUtils.open(setup.item, root, {});
309
310=== modified file 'plugins/hotspot/hotspot.settings'
311--- plugins/hotspot/hotspot.settings 2015-08-12 15:06:37 +0000
312+++ plugins/hotspot/hotspot.settings 2015-09-10 15:34:03 +0000
313@@ -1,6 +1,7 @@
314 {
315 "icon": "preferences-network-hotspot-symbolic",
316 "name": "Hotspot",
317+ "plugin": "hotspot-plugin",
318 "translations": "ubuntu-system-settings",
319 "category": "network",
320 "priority": 2,
321@@ -13,6 +14,6 @@
322 "tethering"
323 ],
324 "has-dynamic-keywords": false,
325- "has-dynamic-visibility": false,
326+ "has-dynamic-visibility": true,
327 "page-component": "PageComponent.qml"
328 }
329
330=== added directory 'plugins/hotspot/plugin'
331=== added file 'plugins/hotspot/plugin/CMakeLists.txt'
332--- plugins/hotspot/plugin/CMakeLists.txt 1970-01-01 00:00:00 +0000
333+++ plugins/hotspot/plugin/CMakeLists.txt 2015-09-10 15:34:03 +0000
334@@ -0,0 +1,8 @@
335+include_directories(${CMAKE_CURRENT_BINARY_DIR})
336+
337+add_definitions(-DQT_NO_KEYWORDS)
338+
339+add_library(hotspot-plugin SHARED hotspot-plugin.h hotspot-plugin.cpp)
340+qt5_use_modules(hotspot-plugin Core Qml DBus)
341+target_link_libraries(hotspot-plugin SystemSettings)
342+install(TARGETS hotspot-plugin DESTINATION ${PLUGIN_MODULE_DIR})
343
344=== added file 'plugins/hotspot/plugin/hotspot-plugin.cpp'
345--- plugins/hotspot/plugin/hotspot-plugin.cpp 1970-01-01 00:00:00 +0000
346+++ plugins/hotspot/plugin/hotspot-plugin.cpp 2015-09-10 15:34:03 +0000
347@@ -0,0 +1,88 @@
348+/*
349+ * This file is part of system-settings
350+ *
351+ * Copyright (C) 2015 Canonical Ltd.
352+ *
353+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
354+ *
355+ * This program is free software: you can redistribute it and/or modify it
356+ * under the terms of the GNU General Public License version 3, as published
357+ * by the Free Software Foundation.
358+ *
359+ * This program is distributed in the hope that it will be useful, but
360+ * WITHOUT ANY WARRANTY; without even the implied warranties of
361+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
362+ * PURPOSE. See the GNU General Public License for more details.
363+ *
364+ * You should have received a copy of the GNU General Public License along
365+ * with this program. If not, see <http://www.gnu.org/licenses/>.
366+ *
367+ */
368+
369+#include "hotspot-plugin.h"
370+
371+#include <QDBusInterface>
372+#include <QDBusPendingReply>
373+#include <QProcessEnvironment>
374+#include <QtDBus>
375+#include <SystemSettings/ItemBase>
376+
377+using namespace SystemSettings;
378+
379+typedef QMap<QString,QString> VersionDetail;
380+Q_DECLARE_METATYPE(VersionDetail)
381+
382+class HotspotItem: public ItemBase
383+{
384+ Q_OBJECT
385+
386+public:
387+ explicit HotspotItem(const QVariantMap &staticData, QObject *parent = 0);
388+ void setVisibility(bool visible);
389+};
390+
391+
392+HotspotItem::HotspotItem(const QVariantMap &staticData, QObject *parent):
393+ ItemBase(staticData, parent)
394+{
395+ qDBusRegisterMetaType<VersionDetail>();
396+
397+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
398+ if (env.contains(QLatin1String("USS_SHOW_ALL_UI"))) {
399+ QString showAllS = env.value("USS_SHOW_ALL_UI", QString());
400+
401+ if(!showAllS.isEmpty()) {
402+ setVisibility(true);
403+ return;
404+ }
405+ }
406+
407+ bool supportedDevice(true);
408+
409+ // TODO: Remove check for mako (lp:1434591).
410+ QDBusInterface m_SystemServiceIface("com.canonical.SystemImage",
411+ "/Service",
412+ "com.canonical.SystemImage",
413+ QDBusConnection::systemBus());
414+ QDBusPendingReply<int, QString, QString, QString, QMap<QString, QString> > reply = m_SystemServiceIface.call("Info");
415+ reply.waitForFinished();
416+ if (reply.isValid()) {
417+ QString device = reply.argumentAt<1>();
418+ supportedDevice = !(device == "mako" || device == "flo");
419+ }
420+
421+ setVisibility(supportedDevice);
422+}
423+
424+void HotspotItem::setVisibility(bool visible)
425+{
426+ setVisible(visible);
427+}
428+
429+ItemBase *HotspotPlugin::createItem(const QVariantMap &staticData,
430+ QObject *parent)
431+{
432+ return new HotspotItem(staticData, parent);
433+}
434+
435+#include "hotspot-plugin.moc"
436
437=== added file 'plugins/hotspot/plugin/hotspot-plugin.h'
438--- plugins/hotspot/plugin/hotspot-plugin.h 1970-01-01 00:00:00 +0000
439+++ plugins/hotspot/plugin/hotspot-plugin.h 2015-09-10 15:34:03 +0000
440@@ -0,0 +1,39 @@
441+/*
442+ * This file is part of system-settings
443+ *
444+ * Copyright (C) 2015 Canonical Ltd.
445+ *
446+ * Contact: Jonas G. Drange <jonas.drange@canonical.com>
447+ *
448+ * This program is free software: you can redistribute it and/or modify it
449+ * under the terms of the GNU General Public License version 3, as published
450+ * by the Free Software Foundation.
451+ *
452+ * This program is distributed in the hope that it will be useful, but
453+ * WITHOUT ANY WARRANTY; without even the implied warranties of
454+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
455+ * PURPOSE. See the GNU General Public License for more details.
456+ *
457+ * You should have received a copy of the GNU General Public License along
458+ * with this program. If not, see <http://www.gnu.org/licenses/>.
459+ *
460+ */
461+
462+#ifndef SYSTEM_SETTINGS_HOTSPOT_PLUGIN_H
463+#define SYSTEM_SETTINGS_HOTSPOT_PLUGIN_H
464+
465+#include <QObject>
466+#include <SystemSettings/PluginInterface>
467+
468+class HotspotPlugin: public QObject, public SystemSettings::PluginInterface2
469+{
470+ Q_OBJECT
471+ Q_PLUGIN_METADATA(IID "com.ubuntu.SystemSettings.PluginInterface/2.0")
472+ Q_INTERFACES(SystemSettings::PluginInterface2)
473+
474+public:
475+ SystemSettings::ItemBase *createItem(const QVariantMap &staticData,
476+ QObject *parent = 0);
477+};
478+
479+#endif // SYSTEM_SETTINGS_HOTSPOT_PLUGIN_H
480
481=== modified file 'tests/autopilot/ubuntu_system_settings/__init__.py'
482--- tests/autopilot/ubuntu_system_settings/__init__.py 2015-08-25 14:09:22 +0000
483+++ tests/autopilot/ubuntu_system_settings/__init__.py 2015-09-10 15:34:03 +0000
484@@ -394,8 +394,11 @@
485 if config:
486 if 'ssid' in config:
487 setup.set_ssid(config['ssid'])
488+ if 'auth' in config:
489+ setup.set_auth(config['auth'])
490 if 'password' in config:
491 setup.set_password(config['password'])
492+ utils.dismiss_osk()
493 setup.enable()
494 if setup:
495 setup.wait_until_destroyed()
496@@ -456,6 +459,11 @@
497 return self.wait_select_single(
498 'Button', objectName='confirmButton')
499
500+ @property
501+ def _password_required_check(self):
502+ return self.wait_select_single(
503+ 'CheckBox', objectName='passwordRequiredToggle')
504+
505 @autopilot.logging.log_action(logger.debug)
506 def set_ssid(self, ssid):
507 self._ssid_field.write(ssid)
508@@ -465,6 +473,13 @@
509 self._password_field.write(password)
510
511 @autopilot.logging.log_action(logger.debug)
512+ def set_auth(self, auth):
513+ if auth == 'wpa-psk':
514+ self._password_required_check.check()
515+ else:
516+ self._password_required_check.uncheck()
517+
518+ @autopilot.logging.log_action(logger.debug)
519 def enable(self):
520 self.pointing_device.click_object(self._enable_button)
521
522
523=== modified file 'tests/autopilot/ubuntu_system_settings/tests/__init__.py'
524--- tests/autopilot/ubuntu_system_settings/tests/__init__.py 2015-08-06 20:05:56 +0000
525+++ tests/autopilot/ubuntu_system_settings/tests/__init__.py 2015-09-10 15:34:03 +0000
526@@ -173,6 +173,75 @@
527 self.add_mock_battery()
528
529
530+class UbuntuSystemSettingsHotspotTestCase(UbuntuSystemSettingsTestCase,
531+ dbusmock.DBusTestCase):
532+ """Base class for tests that tests the hotspot functionality."""
533+ connectivity_parameters = {}
534+ indicatornetwork_parameters = {}
535+ systemimage_parameters = {'device': 'ideal'}
536+
537+ @classmethod
538+ def setUpClass(cls):
539+ cls.session_con = cls.get_dbus(False)
540+
541+ cls.start_system_bus()
542+
543+ si_tmpl = os.path.join(os.path.dirname(__file__), 'systemimage.py')
544+ (cls.si_mock, cls.si_obj) = cls.spawn_server_template(
545+ si_tmpl, parameters=cls.systemimage_parameters,
546+ stdout=subprocess.PIPE)
547+
548+ super(UbuntuSystemSettingsHotspotTestCase, cls).setUpClass()
549+
550+ def setUp(self):
551+ if is_process_running(INDICATOR_NETWORK):
552+ _stop_process(INDICATOR_NETWORK)
553+ self.addCleanup(_start_process, INDICATOR_NETWORK)
554+
555+ ctv_tmpl = os.path.join(os.path.dirname(__file__), 'connectivity.py')
556+ (self.ctv_mock, self.obj_ctv) = self.spawn_server_template(
557+ ctv_tmpl, parameters=self.connectivity_parameters,
558+ stdout=subprocess.PIPE)
559+
560+ self.ctv_private = dbus.Interface(
561+ self.session_con.get_object(CTV_IFACE, CTV_PRIV_OBJ),
562+ 'org.freedesktop.DBus.Properties')
563+
564+ self.ctv_nets = dbus.Interface(
565+ self.session_con.get_object(CTV_IFACE, CTV_NETS_OBJ),
566+ 'org.freedesktop.DBus.Properties')
567+
568+ inetwork = os.path.join(
569+ os.path.dirname(__file__), 'indicatornetwork.py'
570+ )
571+ (self.inetwork_mock, self.obj_inetwork) = self.spawn_server_template(
572+ inetwork, parameters=self.indicatornetwork_parameters,
573+ stdout=subprocess.PIPE)
574+
575+ super(UbuntuSystemSettingsHotspotTestCase, self).setUp()
576+
577+ def tearDown(self):
578+ self.ctv_mock.terminate()
579+ self.ctv_mock.wait()
580+ self.inetwork_mock.terminate()
581+ self.inetwork_mock.wait()
582+ super(UbuntuSystemSettingsHotspotTestCase, self).tearDown()
583+
584+ @classmethod
585+ def tearDownClass(cls):
586+ cls.si_mock.terminate()
587+ cls.si_mock.wait()
588+ if dbusmock.DBusTestCase.system_bus_pid is not None:
589+ cls.stop_dbus(dbusmock.DBusTestCase.system_bus_pid)
590+ del os.environ['DBUS_SYSTEM_BUS_ADDRESS']
591+ dbusmock.DBusTestCase.system_bus_pid = None
592+ if dbusmock.DBusTestCase.session_bus_pid is not None:
593+ cls.stop_dbus(dbusmock.DBusTestCase.session_bus_pid)
594+ del os.environ['DBUS_SESSION_BUS_ADDRESS']
595+ dbusmock.DBusTestCase.session_bus_pid = None
596+ super(UbuntuSystemSettingsHotspotTestCase, cls).tearDownClass()
597+
598+
599 class UbuntuSystemSettingsOfonoTestCase(UbuntuSystemSettingsTestCase,
600 dbusmock.DBusTestCase):
601 """Class for cellular tests which sets up an Ofono mock """
602@@ -395,52 +464,12 @@
603 context.SetProperty(key, value)
604
605
606-class HotspotBaseTestCase(UbuntuSystemSettingsTestCase,
607- dbusmock.DBusTestCase):
608-
609- connectivity_parameters = {}
610- indicatornetwork_parameters = {}
611-
612- @classmethod
613- def setUpClass(cls):
614- cls.session_con = cls.get_dbus(False)
615- super(HotspotBaseTestCase, cls).setUpClass()
616+class HotspotBaseTestCase(UbuntuSystemSettingsHotspotTestCase):
617
618 def setUp(self):
619- if is_process_running(INDICATOR_NETWORK):
620- _stop_process(INDICATOR_NETWORK)
621- self.addCleanup(_start_process, INDICATOR_NETWORK)
622-
623- ctv_tmpl = os.path.join(os.path.dirname(__file__), 'connectivity.py')
624- (self.ctv_mock, self.obj_ctv) = self.spawn_server_template(
625- ctv_tmpl, parameters=self.connectivity_parameters,
626- stdout=subprocess.PIPE)
627-
628- self.ctv_private = dbus.Interface(
629- self.session_con.get_object(CTV_IFACE, CTV_PRIV_OBJ),
630- 'org.freedesktop.DBus.Properties')
631-
632- self.ctv_nets = dbus.Interface(
633- self.session_con.get_object(CTV_IFACE, CTV_NETS_OBJ),
634- 'org.freedesktop.DBus.Properties')
635-
636- inetwork = os.path.join(
637- os.path.dirname(__file__), 'indicatornetwork.py'
638- )
639- (self.inetwork_mock, self.obj_inetwork) = self.spawn_server_template(
640- inetwork, parameters=self.indicatornetwork_parameters,
641- stdout=subprocess.PIPE)
642-
643 super(HotspotBaseTestCase, self).setUp()
644 self.hotspot_page = self.main_view.go_to_hotspot_page()
645
646- def tearDown(self):
647- self.ctv_mock.terminate()
648- self.ctv_mock.wait()
649- self.inetwork_mock.terminate()
650- self.inetwork_mock.wait()
651- super(HotspotBaseTestCase, self).tearDown()
652-
653
654 class BluetoothBaseTestCase(UbuntuSystemSettingsTestCase):
655
656
657=== modified file 'tests/autopilot/ubuntu_system_settings/tests/connectivity.py'
658--- tests/autopilot/ubuntu_system_settings/tests/connectivity.py 2015-08-17 15:35:08 +0000
659+++ tests/autopilot/ubuntu_system_settings/tests/connectivity.py 2015-09-10 15:34:03 +0000
660@@ -47,6 +47,10 @@
661 self.SetProperty(PRIV_OBJ, PRIV_IFACE, 'HotspotPassword', value)
662
663
664+def set_hotspot_auth(self, value):
665+ self.SetProperty(PRIV_OBJ, PRIV_IFACE, 'HotspotAuth', value)
666+
667+
668 def set_wifi_enabled(self, value):
669 self.SetProperty(NETS_OBJ, NETS_IFACE, 'WifiEnabled', value)
670
671@@ -59,6 +63,7 @@
672 mock.set_hotspot_ssid = set_hotspot_ssid
673 mock.set_hotspot_password = set_hotspot_password
674 mock.set_wifi_enabled = set_wifi_enabled
675+ mock.set_hotspot_auth = set_hotspot_auth
676
677 mock.AddObject(
678 NETS_OBJ,
679@@ -95,6 +100,9 @@
680 {
681 'HotspotPassword': _parameters.get(
682 'HotspotPassword', dbus.String('abcdefgh')
683+ ),
684+ 'HotspotAuth': _parameters.get(
685+ 'HotspotAuth', dbus.String('wpa-psk')
686 )
687 },
688 [
689@@ -123,6 +131,10 @@
690 'objects["/"].set_hotspot_password(self, args[0])'
691 ),
692 (
693+ 'SetHotspotAuth', 's', '',
694+ 'objects["/"].set_hotspot_auth(self, args[0])'
695+ ),
696+ (
697 'SetHotspotEnabled', 'b', '',
698 'objects["/"].set_hotspot_enabled(self, args[0])'
699 ),
700
701=== added file 'tests/autopilot/ubuntu_system_settings/tests/systemimage.py'
702--- tests/autopilot/ubuntu_system_settings/tests/systemimage.py 1970-01-01 00:00:00 +0000
703+++ tests/autopilot/ubuntu_system_settings/tests/systemimage.py 2015-09-10 15:34:03 +0000
704@@ -0,0 +1,48 @@
705+'''system image D-BUS mock template'''
706+
707+# This program is free software; you can redistribute it and/or modify it under
708+# the terms of the GNU Lesser General Public License as published by the Free
709+# Software Foundation; either version 3 of the License, or (at your option) any
710+# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
711+# of the license.
712+import dbus
713+
714+__author__ = 'Jonas G. Drange'
715+__email__ = 'jonas.drange@canonical.com'
716+__copyright__ = '(c) 2015 Canonical Ltd.'
717+__license__ = 'LGPL 3+'
718+
719+BUS_NAME = 'com.canonical.SystemImage'
720+MAIN_IFACE = 'com.canonical.SystemImage'
721+MAIN_OBJ = '/Service'
722+SYSTEM_BUS = True
723+
724+
725+def load(mock, parameters):
726+ global _parameters
727+ _parameters = parameters
728+
729+ mock.props = {
730+ 'build_number': _parameters.get('build_number', 0),
731+ 'device': _parameters.get('device', ''),
732+ 'channel': _parameters.get('channel', ''),
733+ 'last_update_date': _parameters.get('last_update_date', ''),
734+ 'last_check_date': _parameters.get('last_check_date', ''),
735+ 'target_build_number': _parameters.get('target_build_number', -1),
736+ 'target_version_detail': _parameters.get('target_version_detail', ''),
737+ 'version_detail': _parameters.get(
738+ 'version_detail', dbus.Dictionary({}, signature='ss')
739+ )
740+ }
741+
742+
743+@dbus.service.method(MAIN_IFACE,
744+ in_signature='', out_signature='isssa{ss}')
745+def Info(self):
746+ return (
747+ self.props['build_number'],
748+ self.props['device'],
749+ self.props['channel'],
750+ self.props['last_update_date'],
751+ self.props['version_detail']
752+ )
753
754=== modified file 'tests/autopilot/ubuntu_system_settings/tests/test_hotspot.py'
755--- tests/autopilot/ubuntu_system_settings/tests/test_hotspot.py 2015-08-17 15:35:08 +0000
756+++ tests/autopilot/ubuntu_system_settings/tests/test_hotspot.py 2015-09-10 15:34:03 +0000
757@@ -56,6 +56,26 @@
758 Eventually(Equals(True))
759 )
760
761+ def test_insecure_setup(self):
762+ ssid = 'bar'
763+ auth = 'none'
764+ config = {'ssid': ssid, 'auth': auth}
765+
766+ self.hotspot_page.setup_hotspot(config)
767+
768+ # Assert that the switch is on.
769+ self.assertTrue(self.hotspot_page.get_hotspot_status())
770+
771+ self.assertThat(
772+ lambda: self.ctv_private.Get(CTV_PRIV_IFACE, 'HotspotAuth'),
773+ Eventually(Equals(auth))
774+ )
775+
776+ self.assertThat(
777+ lambda: self.ctv_nets.Get(CTV_NETS_IFACE, 'HotspotStored'),
778+ Eventually(Equals(True))
779+ )
780+
781
782 class HotspotExistsTestCase(HotspotBaseTestCase):
783
784@@ -80,8 +100,7 @@
785
786 def test_changing(self):
787 ssid = 'bar'
788- password = 'zomgzomg'
789- config = {'ssid': ssid, 'password': password}
790+ config = {'ssid': ssid}
791 self.hotspot_page.setup_hotspot(config)
792
793 self.assertThat(
794@@ -91,11 +110,6 @@
795 Eventually(Equals(ssid))
796 )
797
798- self.assertThat(
799- lambda: self.ctv_private.Get(CTV_PRIV_IFACE, 'HotspotPassword'),
800- Eventually(Equals(password))
801- )
802-
803
804 class HotspotRunningTestCase(HotspotBaseTestCase):
805
806@@ -166,8 +180,7 @@
807
808 def test_setup(self):
809 ssid = 'bar'
810- password = 'zomgzomg'
811- config = {'ssid': ssid, 'password': password}
812+ config = {'ssid': ssid}
813
814 self.assertThat(
815 lambda: self.ctv_nets.Get(CTV_NETS_IFACE, 'HotspotStored'),
816
817=== modified file 'tests/autopilot/ubuntu_system_settings/tests/test_plugins.py'
818--- tests/autopilot/ubuntu_system_settings/tests/test_plugins.py 2015-08-13 13:31:31 +0000
819+++ tests/autopilot/ubuntu_system_settings/tests/test_plugins.py 2015-09-10 15:34:03 +0000
820@@ -12,7 +12,8 @@
821 from ubuntu_system_settings.tests import (
822 UbuntuSystemSettingsTestCase,
823 UbuntuSystemSettingsUpowerTestCase,
824- UbuntuSystemSettingsBatteryTestCase
825+ UbuntuSystemSettingsBatteryTestCase,
826+ UbuntuSystemSettingsHotspotTestCase
827 )
828 from ubuntu_system_settings.utils.i18n import ugettext as _
829
830@@ -175,3 +176,16 @@
831 objectName='entryComponent-battery'
832 )
833 self.assertThat(plugin, NotEquals(None))
834+
835+
836+class SystemSettingsHotspotTestCases(UbuntuSystemSettingsHotspotTestCase):
837+ systemimage_parameters = {'device': 'mako'}
838+
839+ # TODO: remove once lp:1434591 has been resolved.
840+ def test_hotspot_plugin(self):
841+ """ Checks that the Hotspot plugin is not available
842+ as it is broken on mako."""
843+ self.assertThat(lambda: self.main_view.select_single(
844+ objectName='entryComponent-hotspot'),
845+ raises(StateNotFoundError)
846+ )

Subscribers

People subscribed via source and target branches