Merge lp:~pete-woods/ubuntu-system-settings/hotspots-via-indicator into lp:ubuntu-system-settings

Proposed by Pete Woods
Status: Merged
Merged at revision: 1501
Proposed branch: lp:~pete-woods/ubuntu-system-settings/hotspots-via-indicator
Merge into: lp:ubuntu-system-settings
Prerequisite: lp:~jonas-drange/ubuntu-system-settings/hotspots-binding
Diff against target: 1132 lines (+28/-922)
7 files modified
debian/control (+2/-0)
plugins/cellular/CMakeLists.txt (+0/-2)
plugins/cellular/Hotspot.qml (+6/-10)
plugins/cellular/HotspotSetup.qml (+20/-20)
plugins/cellular/hotspotmanager.cpp (+0/-707)
plugins/cellular/hotspotmanager.h (+0/-181)
plugins/cellular/plugin.cpp (+0/-2)
To merge this branch: bzr merge lp:~pete-woods/ubuntu-system-settings/hotspots-via-indicator
Reviewer Review Type Date Requested Status
Jonas G. Drange (community) Needs Information
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+265519@code.launchpad.net

This proposal supersedes a proposal from 2015-07-10.

Commit message

Manage hotspots using connectivity service.

Description of the change

Manage hotspots using connectivity service.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Jonas G. Drange (jonas-drange) wrote : Posted in a previous version of this proposal

Love it, but it uses the old backend which is, like we talked about, deprecated.

review: Needs Fixing
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 :
review: Needs Information

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-07-02 08:59:36 +0000
3+++ debian/control 2015-07-22 16:28:59 +0000
4@@ -23,6 +23,7 @@
5 libunity-api-dev,
6 libupower-glib-dev,
7 pkg-config,
8+ qml-module-ubuntu-connectivity (>= 0.5.2),
9 qt5-default,
10 qtbase5-dev,
11 qtdeclarative5-dev,
12@@ -70,6 +71,7 @@
13 powerd (>= 0.15) | gnome-settings-daemon,
14 qmenumodel-qml,
15 qtdeclarative5-folderlistmodel-plugin,
16+ qml-module-ubuntu-connectivity (>= 0.5.2),
17 qml-module-qtmultimedia | qml-module-qtmultimedia-gles,
18 qtdeclarative5-gsettings1.0 (>=0.1+14.10.20140801.1),
19 qtdeclarative5-ofono0.2 (>=0.70~),
20
21=== modified file 'plugins/cellular/CMakeLists.txt'
22--- plugins/cellular/CMakeLists.txt 2015-07-22 16:28:59 +0000
23+++ plugins/cellular/CMakeLists.txt 2015-07-22 16:28:59 +0000
24@@ -22,8 +22,6 @@
25 add_library(UbuntuCellularPanel MODULE
26 plugin.cpp
27 plugin.h
28- hotspotmanager.cpp
29- hotspotmanager.h
30 ofonoactivator.cpp
31 ofonoactivator.h
32 connectivity.cpp
33
34=== modified file 'plugins/cellular/Hotspot.qml'
35--- plugins/cellular/Hotspot.qml 2015-07-22 16:28:59 +0000
36+++ plugins/cellular/Hotspot.qml 2015-07-22 16:28:59 +0000
37@@ -21,6 +21,7 @@
38 import Ubuntu.Components 0.1
39 import Ubuntu.Components.ListItems 0.1 as ListItem
40 import Ubuntu.Components.Popups 0.1
41+import Ubuntu.Connectivity 1.0
42 import Ubuntu.Settings.Components 0.1 as USC
43 import Ubuntu.SystemSettings.Cellular 1.0
44
45@@ -41,10 +42,6 @@
46 }
47 }
48
49- HotspotManager {
50- id: hotspotManager
51- }
52-
53 Loader {
54 id: setup
55 asynchronous: false
56@@ -57,7 +54,7 @@
57
58 ListItem.Standard {
59 text: i18n.tr("Hotspot")
60- enabled: hotspotManager.stored
61+ enabled: Connectivity.hotspotStored
62 control: Switch {
63 id: hotspotSwitch
64 objectName: "hotspotSwitch"
65@@ -67,8 +64,8 @@
66 id: switchSync
67 userTarget: hotspotSwitch
68 userProperty: "checked"
69- serverTarget: hotspotManager
70- serverProperty: "enabled"
71+ serverTarget: Connectivity
72+ serverProperty: "hotspotEnabled"
73 useWaitBuffer: true
74
75 // Since this blocks the UI thread, we wait until
76@@ -84,7 +81,7 @@
77 id: triggerTimer
78 property bool value
79 interval: 250; repeat: false
80- onTriggered: hotspotManager.enabled = value
81+ onTriggered: Connectivity.hotspotEnabled = value
82 }
83 }
84 }
85@@ -105,13 +102,12 @@
86 objectName: "hotspotSetupEntry"
87 anchors.horizontalCenter: parent.horizontalCenter
88 width: parent.width - units.gu(4)
89- text: hotspotManager.stored ?
90+ text: Connectivity.hotspotStored ?
91 i18n.tr("Change password/setup…") : i18n.tr("Set up hotspot…")
92
93 onClicked: {
94 setup.setSource(Qt.resolvedUrl("HotspotSetup.qml"));
95 PopupUtils.open(setup.item, hotspot, {
96- hotspotManager: hotspotManager
97 });
98 }
99 }
100
101=== modified file 'plugins/cellular/HotspotSetup.qml'
102--- plugins/cellular/HotspotSetup.qml 2015-07-22 16:28:59 +0000
103+++ plugins/cellular/HotspotSetup.qml 2015-07-22 16:28:59 +0000
104@@ -21,6 +21,7 @@
105 import SystemSettings 1.0
106 import Ubuntu.Components 0.1
107 import Ubuntu.Components.ListItems 0.1 as ListItem
108+import Ubuntu.Connectivity 1.0
109 import Ubuntu.SystemSettings.Cellular 1.0
110 import Ubuntu.Components.Popups 0.1
111
112@@ -29,15 +30,14 @@
113
114 Dialog {
115 id: hotspotSetupDialog
116- property var hotspotManager: null
117
118- /* hotspotManager.stored changes as soon as the user has added a
119+ /* Connectivity.hotspotStored changes as soon as the user has added a
120 hotspot, and we use this value when we choose between e.g. "Change" and
121 "Setup". We'd like the narrative to be consistent, so we stick with
122 what the stored value was at component completion.
123 */
124 property bool stored: false
125- Component.onCompleted: stored = hotspotManager.stored;
126+ Component.onCompleted: stored = Connectivity.hotspotStored;
127
128 objectName: "hotspotSetup"
129 anchorToKeyboard: true
130@@ -163,7 +163,7 @@
131 TextField {
132 id: ssidField
133 objectName: "ssidField"
134- text: hotspotManager.ssid
135+ text: Connectivity.hotspotSsid
136 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
137 Component.onCompleted: forceActiveFocus()
138 width: parent.width
139@@ -182,7 +182,7 @@
140 TextField {
141 id: passwordField
142 objectName: "passwordField"
143- text: hotspotManager.password
144+ text: Connectivity.hotspotPassword
145 echoMode: passwordVisibleSwitch.checked ?
146 TextInput.Normal : TextInput.Password
147 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
148@@ -262,15 +262,15 @@
149 function hotspotEnabledHandler (enabled) {
150 if (enabled) {
151 hotspotSetupDialog.state = "SUCCEEDED";
152- hotspotManager.enabledChanged.disconnect(
153+ Connectivity.hotspotEnabledUpdated.disconnect(
154 hotspotEnabledHandler);
155 }
156 }
157
158- hotspotManager.ssid = ssidField.text;
159- hotspotManager.password = passwordField.text;
160- hotspotManager.enabledChanged.connect(hotspotEnabledHandler);
161- hotspotManager.enabled = true;
162+ Connectivity.hotspotSsid = ssidField.text;
163+ Connectivity.hotspotPassword = passwordField.text;
164+ Connectivity.hotspotEnabledUpdated.connect(hotspotEnabledHandler);
165+ Connectivity.hotspotEnabled = true;
166 }
167 }
168
169@@ -282,28 +282,28 @@
170 function hotspotEnabledHandler (enabled) {
171 if (enabled) {
172 hotspotSetupDialog.state = "SUCCEEDED";
173- hotspotManager.enabledChanged.disconnect(
174+ Connectivity.hotspotEnabledUpdated.disconnect(
175 hotspotEnabledHandler);
176 }
177 }
178
179 function hotspotDisabledHandler (enabled) {
180 if (!enabled) {
181- hotspotManager.enabledChanged.connect(hotspotEnabledHandler);
182- hotspotManager.enabled = true;
183- hotspotManager.enabledChanged.disconnect(
184+ Connectivity.hotspotEnabledUpdated.connect(hotspotEnabledHandler);
185+ Connectivity.hotspotEnabled = true;
186+ Connectivity.hotspotEnabledUpdated.disconnect(
187 hotspotDisabledHandler);
188 }
189 }
190
191- hotspotManager.ssid = ssidField.text;
192- hotspotManager.password = passwordField.text;
193+ Connectivity.hotspotSsid = ssidField.text;
194+ Connectivity.hotspotPassword = passwordField.text;
195
196- if (hotspotManager.enabled) {
197+ if (Connectivity.hotspotEnabled) {
198 hotspotSetupDialog.state = "STARTING";
199- hotspotManager.enabledChanged.connect(
200+ Connectivity.hotspotEnabledUpdated.connect(
201 hotspotDisabledHandler);
202- hotspotManager.enabled = false;
203+ Connectivity.hotspotEnabled = false;
204 } else {
205 PopupUtils.close(hotspotSetupDialog);
206 }
207@@ -321,7 +321,7 @@
208 }
209
210 Connections {
211- target: hotspotManager
212+ target: Connectivity
213
214 onReportError: {
215 if (hotspotSetupDialog.state === "STARTING") {
216
217=== removed file 'plugins/cellular/hotspotmanager.cpp'
218--- plugins/cellular/hotspotmanager.cpp 2015-07-22 16:28:59 +0000
219+++ plugins/cellular/hotspotmanager.cpp 1970-01-01 00:00:00 +0000
220@@ -1,707 +0,0 @@
221-/*
222- * Copyright (C) 2014, 2015 Canonical, Ltd.
223- *
224- * Authors:
225- * Jussi Pakkanen <jussi.pakkanen@canonical.com>
226- * Jonas G. Drange <jonas.drange@canonical.com>
227- *
228- * This program is free software: you can redistribute it and/or modify it
229- * under the terms of the GNU General Public License version 3, as published
230- * by the Free Software Foundation.
231- *
232- * This library is distributed in the hope that it will be useful, but WITHOUT
233- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
234- * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
235- * details.
236- *
237- * You should have received a copy of the GNU General Public License
238- * along with this program. If not, see <http://www.gnu.org/licenses/>.
239-*/
240-
241-#include "hotspotmanager.h"
242-#include <QStringList>
243-#include <QDBusReply>
244-#include <QtDebug>
245-#include <QDBusInterface>
246-#include <QDBusMetaType>
247-
248-typedef QMap<QString, QVariantMap> nmConnectionArg;
249-Q_DECLARE_METATYPE(nmConnectionArg)
250-
251-namespace { // wpa_supplicant interaction
252-
253-const QString wpa_supplicant_service("fi.w1.wpa_supplicant1");
254-const QString wpa_supplicant_interface("fi.w1.wpa_supplicant1");
255-const QString wpa_supplicant_path("/fi/w1/wpa_supplicant1");
256-
257-bool isHybrisWlan() {
258- QString program("getprop");
259- QStringList arguments;
260- arguments << "urfkill.hybris.wlan";
261-
262- QProcess *getprop = new QProcess();
263- getprop->start(program, arguments);
264-
265- if (!getprop->waitForFinished()) {
266- qCritical() << "getprop process failed:" << getprop->errorString();
267- delete getprop;
268- return false;
269- }
270-
271- int index = getprop->readAllStandardOutput().indexOf("1");
272- delete getprop;
273-
274- // A non-negative integer means getprop returned 1
275- return index >= 0;
276-}
277-
278-// True if changed successfully, or there was no need. Otherwise false.
279-// Supported modes are 'p2p', 'sta' and 'ap'.
280-bool changeInterfaceFirmware(const QString interface, const QString mode) {
281- // Not supported.
282- if (mode == "adhoc") {
283- return true;
284- }
285-
286- if (isHybrisWlan()) {
287- QDBusInterface wpasIface (
288- wpa_supplicant_service, wpa_supplicant_path, wpa_supplicant_interface,
289- QDBusConnection::systemBus());
290-
291- const QDBusObjectPath interface_path(interface);
292-
293- // TODO(jgdx): We need to guard against calling this
294- // when the interface is not soft blocked.
295- auto set_interface = wpasIface.call("SetInterfaceFirmware",
296- QVariant::fromValue(interface_path), QVariant(mode));
297-
298- if (set_interface.type() == QDBusMessage::ErrorMessage) {
299- qCritical() << "Failed to change interface firmware:"
300- << set_interface.errorMessage();
301- return false;
302- } else {
303- return true;
304- }
305- }
306-
307- // We had no need to change the firmware.
308- return true;
309-}
310-} // wpa_supplicant interaction
311-
312-namespace { // UrfKill interaction
313-
314-const QString urfkill_service("org.freedesktop.URfkill");
315-const QString urfkill_interface("org.freedesktop.URfkill");
316-const QString urfkill_path("/org/freedesktop/URfkill");
317-
318-// True if call went through and returned true.
319-bool setWifiBlock(bool block) {
320- QDBusInterface urfkill_dbus_interface(urfkill_service, urfkill_path,
321- urfkill_interface, QDBusConnection::systemBus());
322-
323- const unsigned int device_type = 1; /* wifi type */
324- auto reply = urfkill_dbus_interface.call("Block", device_type, block);
325-
326- if (reply.type() == QDBusMessage::ErrorMessage) {
327- qCritical() << "Failed to block wifi" << reply.errorMessage();
328- return false;
329- }
330-
331- // We got exactly one argument back, and it's not an error.
332- if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 1) {
333- // returned false from call
334- if (!qdbus_cast<bool>(reply.arguments().at(0))) {
335- qCritical() << "URfkill Block call did not succeed";
336- return false;
337- } else {
338- return true;
339- }
340- }
341- // We did not get what we wanted from dbus, so we treat that as failure.
342- return false;
343-}
344-} // UrfKill interaction
345-
346-namespace { // NetworkManager interaction
347-
348-const QString nm_service("org.freedesktop.NetworkManager");
349-const QString nm_object("/org/freedesktop/NetworkManager");
350-const QString nm_settings_object("/org/freedesktop/NetworkManager/Settings");
351-const QString nm_settings_interface("org.freedesktop.NetworkManager.Settings");
352-const QString nm_connection_interface("org.freedesktop.NetworkManager.Settings.Connection");
353-const QString nm_connection_active_interface("org.freedesktop.NetworkManager.Connection.Active");
354-const QString nm_device_interface("org.freedesktop.NetworkManager.Device");
355-const QString dbus_properties_interface("org.freedesktop.DBus.Properties");
356-const QString connection_property("Connection");
357-
358-// NetworkManager dbus interface proxy we will use to query
359-// against NetworkManager. See
360-// https://developer.gnome.org/NetworkManager/0.9/spec.html
361-// #org.freedesktop.NetworkManager
362-OrgFreedesktopNetworkManagerInterface nm_manager(
363- nm_service, nm_object, QDBusConnection::systemBus());
364-
365-// NetworkManager Settings interface proxy we use to get
366-// the list of connections, as well as adding connections.
367-// See https://developer.gnome.org/NetworkManager/0.9/spec.html
368-// #org.freedesktop.NetworkManager.Settings
369-OrgFreedesktopNetworkManagerSettingsInterface nm_settings(
370- nm_service, nm_settings_object, QDBusConnection::systemBus());
371-
372-// Helper that maps QStrings to other QVariantMaps, i.e.
373-// QMap<QString, QVariantMap>. QVariantMap is an alias for
374-// QMap<QString, QVariant>.
375-// See http://doc.qt.io/qt-5/qvariant.html#QVariantMap-typedef and
376-// https://developer.gnome.org/NetworkManager/0.9/spec.html
377-// #type-String_String_Variant_Map_Map
378-nmConnectionArg createConnectionSettings(
379- const QByteArray &ssid, const QString &password,
380- const QDBusObjectPath &devicePath, QString mode, bool autoConnect = true) {
381- Q_UNUSED(devicePath);
382- nmConnectionArg connection;
383-
384- QString s_ssid = QString::fromLatin1(ssid);
385- QString s_uuid = QUuid().createUuid().toString();
386- // Remove {} from the generated uuid.
387- s_uuid.remove(0, 1);
388- s_uuid.remove(s_uuid.size() - 1, 1);
389-
390- QVariantMap wireless;
391- wireless[QStringLiteral("security")] = QVariant(QStringLiteral("802-11-wireless-security"));
392- wireless[QStringLiteral("ssid")] = QVariant(ssid);
393- wireless[QStringLiteral("mode")] = QVariant(mode);
394-
395- connection["802-11-wireless"] = wireless;
396-
397- QVariantMap connsettings;
398- connsettings[QStringLiteral("autoconnect")] = QVariant(autoConnect);
399- connsettings[QStringLiteral("id")] = QVariant(s_ssid);
400- connsettings[QStringLiteral("uuid")] = QVariant(s_uuid);
401- connsettings[QStringLiteral("type")] = QVariant(QStringLiteral("802-11-wireless"));
402- connection["connection"] = connsettings;
403-
404- QVariantMap ipv4;
405- ipv4[QStringLiteral("addressess")] = QVariant(QStringList());
406- ipv4[QStringLiteral("dns")] = QVariant(QStringList());
407- ipv4[QStringLiteral("method")] = QVariant(QStringLiteral("shared"));
408- ipv4[QStringLiteral("routes")] = QVariant(QStringList());
409- connection["ipv4"] = ipv4;
410-
411- QVariantMap ipv6;
412- ipv6[QStringLiteral("method")] = QVariant(QStringLiteral("ignore"));
413- connection["ipv6"] = ipv6;
414-
415- QVariantMap security;
416- security[QStringLiteral("proto")] = QVariant(QStringList{"rsn"});
417- security[QStringLiteral("pairwise")] = QVariant(QStringList{"ccmp"});
418- security[QStringLiteral("group")] = QVariant(QStringList{"ccmp"});
419- security[QStringLiteral("key-mgmt")] = QVariant(QStringLiteral("wpa-psk"));
420- security[QStringLiteral("psk")] = QVariant(password);
421- connection["802-11-wireless-security"] = security;
422-
423- return connection;
424-}
425-
426-// Helper that returns a QMap<QString, QVariantMap> given a QDBusObjectPath.
427-// See https://developer.gnome.org/NetworkManager/0.9/spec.html
428-// #org.freedesktop.NetworkManager.Settings.Connection.GetSettings
429-nmConnectionArg getConnectionSettings (QDBusObjectPath connection) {
430- OrgFreedesktopNetworkManagerSettingsConnectionInterface conn(
431- nm_service, connection.path(), QDBusConnection::systemBus());
432-
433- auto connection_settings = conn.GetSettings();
434- connection_settings.waitForFinished();
435- return connection_settings.value();
436-}
437-
438-
439-// Helper that returns a QMap<QString, QVariantMap> given a QDBusObjectPath.
440-// See https://developer.gnome.org/NetworkManager/0.9/spec.html
441-// #org.freedesktop.NetworkManager.Settings.Connection.GetSettings
442-nmConnectionArg getConnectionSecrets (QDBusObjectPath connection,
443- const QString key) {
444- OrgFreedesktopNetworkManagerSettingsConnectionInterface conn(
445- nm_service, connection.path(), QDBusConnection::systemBus());
446- auto connection_secrets = conn.GetSecrets(key);
447- connection_secrets.waitForFinished();
448- return connection_secrets.value();
449-}
450-
451-// Helper that adds a connection and returns the QDBusObjectPath
452-// of the newly created connection.
453-// See https://developer.gnome.org/NetworkManager/0.9/spec.html
454-// #org.freedesktop.NetworkManager.Settings.AddConnection
455-QDBusObjectPath addConnection(
456- const QByteArray &ssid, const QString &password,
457- const QDBusObjectPath &devicePath, QString mode) {
458-
459- nmConnectionArg connection = createConnectionSettings(ssid, password,
460- devicePath, mode);
461-
462- auto add_connection_reply = nm_settings.AddConnection(connection);
463- add_connection_reply.waitForFinished();
464-
465- if(!add_connection_reply.isValid()) {
466- qCritical() << "Failed to add connection: "
467- << add_connection_reply.error().message();
468- return QDBusObjectPath();
469- }
470- return add_connection_reply.argumentAt<0>();
471-}
472-
473-// Returns a QDBusObjectPath of a hotspot given a mode.
474-// Valid modes are 'p2p', 'ap' and 'adhoc'.
475-QDBusObjectPath getHotspot(QString mode) {
476- const char wifi_key[] = "802-11-wireless";
477-
478- auto listed_connections = nm_settings.ListConnections();
479- listed_connections.waitForFinished();
480-
481- for(const auto &connection : listed_connections.value()) {
482- OrgFreedesktopNetworkManagerSettingsConnectionInterface conn(
483- nm_service, connection.path(), QDBusConnection::systemBus());
484-
485- auto connection_settings = getConnectionSettings(connection);
486-
487- if(connection_settings.find(wifi_key) != connection_settings.end()) {
488- auto wifi_setup = connection_settings[wifi_key];
489- QString wifi_mode = wifi_setup["mode"].toString();
490-
491- if(wifi_mode == mode) {
492- return connection;
493- }
494- }
495- }
496- return QDBusObjectPath();
497-}
498-
499-// Returns a QDBusObjectPath of a wireless device. For now
500-// it returns the first device.
501-QDBusObjectPath getWirelessDevice () {
502- // find the first wlan adapter for now
503- auto reply1 = nm_manager.GetDevices();
504- reply1.waitForFinished();
505-
506- if(!reply1.isValid()) {
507- qCritical() << "Could not get network device: "
508- << reply1.error().message();
509- return QDBusObjectPath();
510- }
511- auto devices = reply1.value();
512-
513- QDBusObjectPath dev;
514- for (const auto &d : devices) {
515- QDBusInterface iface(nm_service, d.path(), nm_device_interface,
516- QDBusConnection::systemBus());
517- auto type_v = iface.property("DeviceType");
518-
519- if (type_v.toUInt() == 2 /* NM_DEVICE_TYPE_WIFI */) {
520- return d;
521- }
522- }
523- qCritical() << "Wireless device not found, hotspot functionality is inoperative.";
524- return dev;
525-}
526-
527-// Helper to check if the hotspot on a given QDBusObjectPath is active
528-// or not. It checks if the Connection.Active [1] for the given
529-// path is in NetworkManager's ActiveConnections property [2].
530-// [1] https://developer.gnome.org/NetworkManager/0.9/spec.html
531-// #org.freedesktop.NetworkManager.Connection.Active
532-// [2] https://developer.gnome.org/NetworkManager/0.9/spec.html
533-// #org.freedesktop.NetworkManager
534-bool isHotspotActive (QDBusObjectPath path) {
535- QSet<QDBusObjectPath> active_relevant_connections;
536- auto active_connections = nm_manager.activeConnections();
537- for(const auto &active_connection : active_connections) {
538-
539- // Active connection interface proxy. It might have a connection
540- // property we can use to deduce if this active connection represents
541- // our active hotspot.
542- QDBusInterface active_connection_dbus_interface(
543- nm_service, active_connection.path(), dbus_properties_interface,
544- QDBusConnection::systemBus());
545-
546- // Get the Connection property, if any.
547- QDBusReply<QVariant> connection_property =
548- active_connection_dbus_interface.call("Get",
549- nm_connection_active_interface, "Connection");
550-
551- // The Connection property did not exist, so ignore this
552- // active connection.
553- if(!connection_property.isValid()) {
554- continue;
555- }
556-
557- // It does exist, cast it to a object path.
558- QDBusObjectPath connection_path = qvariant_cast<QDBusObjectPath>(
559- connection_property.value());
560-
561- // The object path is the same as the given hotspot path.
562- if (path == connection_path) {
563- return true;
564- }
565- }
566-
567- // No active connection had a Connection property equal to the
568- // given path, so return false.
569- return false;
570-}
571-
572-std::string generate_password() {
573- static const std::string items("abcdefghijklmnopqrstuvwxyz01234567890");
574- const int password_length = 8;
575- std::string result;
576-
577- for(int i=0; i<password_length; i++) {
578- result.push_back(items[std::rand() % items.length()]);
579- }
580- return result;
581-}
582-} // NetworkManager interaction
583-
584-HotspotManager::HotspotManager(QObject *parent) :
585- QObject(parent), m_mode("ap"), m_enabled(false), m_stored(false),
586- m_password(generate_password().c_str()), m_ssid(QByteArray("Ubuntu")),
587- m_device_path(getWirelessDevice()) {
588- static bool isRegistered = false;
589-
590- if(!isRegistered) {
591- qDBusRegisterMetaType<nmConnectionArg>();
592- isRegistered = true;
593- }
594-
595- // Stored is false if hotspot path is empty.
596- m_hotspot_path = getHotspot(m_mode);
597- setStored(!m_hotspot_path.path().isEmpty());
598-
599- if (m_stored) {
600- updateSettingsFromDbus(m_hotspot_path);
601- }
602-
603- // Watches for new connections added to NetworkManager's Settings
604- // interface.
605- nm_settings.connection().connect(
606- nm_settings.service(), nm_settings_object, nm_settings_interface,
607- "NewConnection", this, SLOT(onNewConnection(QDBusObjectPath)));
608-
609- // Watches changes in NetworkManager.
610- nm_manager.connection().connect(
611- nm_manager.service(), nm_object, nm_service, "PropertiesChanged", this,
612- SLOT(onPropertiesChanged(QMap<QString, QVariant>)));
613-}
614-
615-void HotspotManager::setEnabled(bool value) {
616- bool blocked = setWifiBlock(true);
617-
618- // Failed to soft block, here we revert the enabled setting.
619- if (!blocked) {
620- // "The device could not be readied for configuration"
621- Q_EMIT reportError(5);
622- setEnable(false);
623- return;
624- }
625-
626- // We are enabling a hotspot
627- if (value) {
628- // If the SSID is empty, we report an error.
629- if (m_ssid.isEmpty()) {
630- Q_EMIT reportError(1);
631- setEnable(false);
632- return;
633- }
634-
635- bool changed = changeInterfaceFirmware("/", m_mode);
636- if (!changed) {
637- // Necessary firmware for the device may be missing
638- Q_EMIT reportError(35);
639- setEnable(false);
640- setWifiBlock(false);
641- return;
642- }
643-
644- if (m_stored) {
645- // we defer enabling until old hotspot is deleted
646- // if we can delete the old one
647- // If not, unset stored flag and call this method.
648- if (!destroy(m_hotspot_path)) {
649- setStored(false);
650- setEnabled(true);
651- setEnable(true);
652- }
653- } else {
654- // we defer enabling until new hotspot is created
655- m_hotspot_path = addConnection(m_ssid, m_password, m_device_path, m_mode);
656- if (m_hotspot_path.path().isEmpty()) {
657- // Emit "Unknown Error".
658- Q_EMIT reportError(0);
659- setEnable(false);
660- setWifiBlock(false);
661- }
662- }
663-
664- } else {
665- // Disabling the hotspot.
666- disable();
667- setEnable(false);
668-
669- bool unblocked = setWifiBlock(false);
670- if (!unblocked) {
671- // "The device could not be readied for configuration"
672- Q_EMIT reportError(5);
673- }
674- }
675-}
676-
677-// Disables a hotspot.
678-void HotspotManager::disable() {
679- QDBusObjectPath hotspot = getHotspot(m_mode);
680- if (hotspot.path().isEmpty()) {
681- qWarning() << "Could not find a hotspot setup to disable.\n";
682- return;
683- }
684-
685- // Create Connection.Settings proxy for hotspot
686- OrgFreedesktopNetworkManagerSettingsConnectionInterface conn(
687- nm_service, hotspot.path(), QDBusConnection::systemBus());
688-
689- // Get new settings
690- nmConnectionArg new_settings = createConnectionSettings(m_ssid, m_password,
691- m_device_path, m_mode, false);
692- auto updating = conn.Update(new_settings);
693- updating.waitForFinished();
694- if(!updating.isValid()) {
695- qCritical() << "Could not update connection with autoconnect=false: "
696- << updating.error().message();
697- }
698-
699- auto active_connections = nm_manager.activeConnections();
700- for(const auto &active_connection : active_connections) {
701- // DBus Properties interface proxy of the active connection. We use
702- // this proxy to get to the Connection property.
703- QDBusInterface iface(
704- nm_service, active_connection.path(),
705- "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
706-
707- // Call to get the Connection property.
708- QDBusReply<QVariant> conname = iface.call(
709- "Get", nm_connection_active_interface, "Connection");
710-
711- // Cast the property to a object path.
712- QDBusObjectPath backingConnection = qvariant_cast<QDBusObjectPath>(
713- conname.value());
714-
715- // This active connection's Connection property was our hotspot,
716- // so we will deactivate it. Note that we do not remove the hotspot,
717- // as we are storing the ssid, password and mode on the connection.
718- if(backingConnection == m_hotspot_path) {
719- // Deactivate the connection.
720- auto deactivation = nm_manager.DeactivateConnection(active_connection);
721- deactivation.waitForFinished();
722- if(!deactivation.isValid()) {
723- qCritical() << "Could not get deactivate connection: "
724- << deactivation.error().message();
725- }
726- return;
727- }
728- }
729- return;
730-}
731-
732-bool HotspotManager::enabled() const {
733- return m_enabled;
734-}
735-
736-void HotspotManager::setEnable(bool value) {
737- if (m_enabled != value) {
738- m_enabled = value;
739- Q_EMIT enabledChanged(value);
740- }
741-}
742-
743-bool HotspotManager::stored() const {
744- return m_stored;
745-}
746-
747-void HotspotManager::setStored(bool value) {
748- if (m_stored != value) {
749- m_stored = value;
750- Q_EMIT storedChanged(value);
751- }
752-}
753-
754-QByteArray HotspotManager::ssid() const {
755- return m_ssid;
756-}
757-
758-void HotspotManager::setSsid(QByteArray value) {
759- if (m_ssid != value) {
760- m_ssid = value;
761- Q_EMIT ssidChanged(value);
762- }
763-}
764-
765-QString HotspotManager::password() const {
766- return m_password;
767-}
768-
769-void HotspotManager::setPassword(QString value) {
770- if (m_password != value) {
771- m_password = value;
772- Q_EMIT passwordChanged(value);
773- }
774-}
775-
776-QString HotspotManager::mode() const {
777- return m_mode;
778-}
779-
780-void HotspotManager::setMode(QString value) {
781- if (m_mode != value) {
782- m_mode = value;
783- Q_EMIT modeChanged(value);
784- }
785-}
786-
787-void HotspotManager::onNewConnection(QDBusObjectPath path) {
788- // The new connection is the same as the stored hotspot path.
789- if (path == m_hotspot_path) {
790- // If a new hotspot was added, it is also given that
791- // Wi-Fi has been soft blocked. We can now unblock Wi-Fi
792- // and let NetworkManager pick up the newly created
793- // connection.
794- bool unblocked = setWifiBlock(false);
795- if (!unblocked) {
796- // "The device could not be readied for configuration"
797- Q_EMIT reportError(5);
798- } else {
799- // We successfully unblocked the Wi-Fi, so set m_enable to true.
800- setEnable(true);
801- }
802-
803- // This also mean we have successfully created a hotspot connection
804- // object in NetworkManager, so m_stored should now be true.
805- setStored(true);
806- }
807-}
808-
809-
810-bool HotspotManager::destroy(QDBusObjectPath path) {
811- if(path.path().isEmpty()) {
812- return false;
813- }
814-
815- // Connection Settings interface proxy for the connection
816- // we are about to delete.
817- OrgFreedesktopNetworkManagerSettingsConnectionInterface conn(
818- nm_service, path.path(), QDBusConnection::systemBus());
819-
820- // Subscribe to the connection proxy's Removed signal.
821- conn.connection().connect(conn.service(), path.path(), conn.interface(),
822- "Removed", this, SLOT(onRemoved()));
823-
824- auto del = conn.Delete();
825- del.waitForFinished();
826- return del.isValid();
827-}
828-
829-void HotspotManager::onRemoved() {
830- // The UI does not support direct deletion of a hotspot, and given how
831- // hotspots currently work, every time we want to re-use a hotspot, we
832- // delete it an add a new one.
833- // Thus, if a hotspot was deleted, we now create a new one.
834- m_hotspot_path = addConnection(m_ssid, m_password, m_device_path, m_mode);
835-
836- // We could not add a connection, so report, disable and unblock.
837- if (m_hotspot_path.path().isEmpty()) {
838- // Emit "Unknown Error".
839- Q_EMIT reportError(0);
840- setEnable(false);
841- setWifiBlock(false);
842- }
843-}
844-
845-void HotspotManager::onPropertiesChanged(QVariantMap properties) {
846- // If we have no hotspot path, ignore changes in NetworkManager.
847- if (m_hotspot_path.path().isEmpty()) {
848- return;
849- }
850-
851- // Set flag so we know that ActiveConnections changed.
852- bool active_connection_changed = false;
853-
854- for(QVariantMap::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) {
855- if (iter.key() == "ActiveConnections") {
856- active_connection_changed = true;
857-
858- const QDBusArgument args = qvariant_cast<QDBusArgument>(iter.value());
859- if (args.currentType() == QDBusArgument::ArrayType) {
860- args.beginArray();
861-
862- while (!args.atEnd()) {
863- QDBusObjectPath path = qdbus_cast<QDBusObjectPath>(args);
864-
865- QDBusInterface active_connection_dbus_interface(
866- nm_service, path.path(), dbus_properties_interface,
867- QDBusConnection::systemBus());
868-
869- QDBusReply<QVariant> connection_property = active_connection_dbus_interface.call(
870- "Get", nm_connection_active_interface, "Connection");
871-
872- // Active connection did not have a connection property,
873- // so ignore it.
874- if(!connection_property.isValid()) {
875- continue;
876- }
877-
878- QDBusObjectPath connection_path = qvariant_cast<QDBusObjectPath>(
879- connection_property.value());
880-
881- // We see our connection as being active, so we emit that is
882- // enabled and return.
883- if (connection_path == m_hotspot_path) {
884- setEnable(true);
885- return;
886- }
887- }
888- args.endArray();
889- }
890- }
891- }
892-
893- // At this point ActiveConnections changed, but
894- // our hotspot was not in that list.
895- if (active_connection_changed) {
896- setEnable(false);
897- }
898-}
899-
900-void HotspotManager::updateSettingsFromDbus(QDBusObjectPath path) {
901- setEnable(isHotspotActive(m_hotspot_path));
902-
903- nmConnectionArg settings = getConnectionSettings(path);
904- const char wifi_key[] = "802-11-wireless";
905- const char security_key[] = "802-11-wireless-security";
906-
907- if (settings.find(wifi_key) != settings.end()) {
908- QByteArray ssid = settings[wifi_key]["ssid"].toByteArray();
909- if (!ssid.isEmpty()) {
910- setSsid(ssid);
911- }
912-
913- QString mode = settings[wifi_key]["mode"].toString();
914- if (!mode.isEmpty()) {
915- setMode(mode);
916- }
917- }
918-
919- nmConnectionArg secrets = getConnectionSecrets(path, security_key);
920-
921- if (secrets.find(security_key) != secrets.end()) {
922- QString pwd = secrets[security_key]["psk"].toString();
923- if (!pwd.isEmpty()) {
924- setPassword(pwd);
925- }
926- }
927-}
928
929=== removed file 'plugins/cellular/hotspotmanager.h'
930--- plugins/cellular/hotspotmanager.h 2015-07-22 16:28:59 +0000
931+++ plugins/cellular/hotspotmanager.h 1970-01-01 00:00:00 +0000
932@@ -1,181 +0,0 @@
933-/*
934- * Copyright (C) 2014, 2015 Canonical, Ltd.
935- *
936- * Authors:
937- * Jussi Pakkanen <jussi.pakkanen@canonical.com>
938- * Jonas G. Drange <jonas.drange@canonical.com>
939- *
940- * This program is free software: you can redistribute it and/or modify it
941- * under the terms of the GNU General Public License version 3, as published
942- * by the Free Software Foundation.
943- *
944- * This library is distributed in the hope that it will be useful, but WITHOUT
945- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
946- * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
947- * details.
948- *
949- * You should have received a copy of the GNU General Public License
950- * along with this program. If not, see <http://www.gnu.org/licenses/>.
951- *
952- *
953- * HotspotManager API
954- * ==============================
955- *
956- * Methods
957- *
958- * Signals
959- * enabledChanged(bool enabled)
960- * Signal that gets emitted when the hotspot is disabled or enabled.
961- *
962- * storedChanged(bool stored)
963- * Signal that gets emitted when a hotspot was stored.
964- *
965- * ssidChanged(QByteArray ssid)
966- * Signal that gets emitted when the ssid of the hotspot was changed.
967- *
968- * passwordChanged(QString password)
969- * Signal that gets emitted when the password of the hotspot was changed.
970- *
971- * modeChanged(QString mode)
972- * Signal that gets emitted when the mode was changed.
973- *
974- * authChanged(QString auth)
975- *
976- * Note that none of these signal will be emitted if a change to the hotspot
977- * was made by anyone else than the HotspotManager. Right now, the canonical
978- * way to edit a hotspot, is through the hotspot manager.
979- *
980- *
981- * reportError(int reason)
982- * The reasons correspond to https://developer.gnome.org/
983- * NetworkManager/0.9/spec.html#type-NM_DEVICE_STATE_REASON
984- *
985- * Properties
986- * bool enabled [readwrite]
987- * Whether or not the hotspot is enabled.
988- *
989- * bool stored [readonly]
990- * Whether or not a hotspot is known to the hotspotmanager.
991- *
992- * QByteArray ssid [readwrite]
993- * The current SSID of the hotspot.
994- *
995- * QString auth [readwrite]
996- * The current authentication of the hotspot. The default for this property
997- * is "wpa-psk" and is currently the only supported scheme. WEP is unsupported
998- * by design, as is no scheme at all.
999- *
1000- * TODO: Check/add support for wpa-eap
1001- *
1002- * QString password [readwrite]
1003- * The current Pre-Shared-Key for the hotspot. If the key is 64-characters
1004- * long, it must contain only hexadecimal characters and is interpreted as a
1005- * hexadecimal WPA key. Otherwise, the key must be between 8 and 63 ASCII
1006- * characters and is interpreted as a WPA passphrase.
1007- *
1008- * QString mode [readwrite, optional]
1009- * The current hotspot mode. The default of this value is "ap", but can be
1010- * set to "p2p" or "adhoc". "p2p" and "adhoc" is currently not fully supported.
1011- *
1012- * TODO: Complete support for adhoc and p2p modes.
1013-*/
1014-
1015-#ifndef HOTSPOTMANAGER_H
1016-#define HOTSPOTMANAGER_H
1017-
1018-#include <QObject>
1019-#include <QDBusObjectPath>
1020-#include <QUuid>
1021-
1022-#include "nm_manager_proxy.h"
1023-#include "nm_settings_proxy.h"
1024-#include "nm_settings_connection_proxy.h"
1025-
1026-class HotspotManager : public QObject {
1027- Q_OBJECT
1028- Q_PROPERTY( bool enabled
1029- READ enabled
1030- WRITE setEnabled
1031- NOTIFY enabledChanged)
1032- Q_PROPERTY( QByteArray ssid
1033- READ ssid
1034- WRITE setSsid
1035- NOTIFY ssidChanged)
1036- Q_PROPERTY( QString auth
1037- READ auth
1038- WRITE setAuth
1039- NOTIFY authChanged)
1040- Q_PROPERTY( QString password
1041- READ password
1042- WRITE setPassword
1043- NOTIFY passwordChanged)
1044- Q_PROPERTY( QString mode
1045- READ mode
1046- WRITE setMode
1047- NOTIFY modeChanged)
1048- Q_PROPERTY( bool stored
1049- READ stored
1050- NOTIFY storedChanged)
1051-
1052-public:
1053- explicit HotspotManager(QObject *parent = nullptr);
1054- ~HotspotManager() {};
1055-
1056- bool enabled() const;
1057- void setEnabled(bool);
1058- bool stored() const;
1059-
1060- QByteArray ssid() const;
1061- void setSsid(QByteArray);
1062-
1063- QString password() const;
1064- void setPassword(QString);
1065-
1066- QString mode() const;
1067- void setMode(QString);
1068-
1069- QString auth() const;
1070- void setAuth(QString);
1071-
1072-Q_SIGNALS:
1073- void enabledChanged(bool enabled);
1074- void storedChanged(bool stored);
1075- void ssidChanged(const QByteArray ssid);
1076- void passwordChanged(const QString password);
1077- void modeChanged(const QString mode);
1078- void authChanged(const QString auth);
1079-
1080- /*
1081- The mapping of code to string is taken from
1082- http://bazaar.launchpad.net/~vcs-imports/
1083- network-manager/trunk/view/head:/cli/src/common.c
1084-
1085- NetworkManager documentation: https://developer.gnome.org/
1086- NetworkManager/0.9/spec.html#type-NM_DEVICE_STATE_REASON
1087- */
1088- void reportError(const int &reason);
1089-
1090-public Q_SLOTS:
1091- void onNewConnection(const QDBusObjectPath);
1092- void onRemoved();
1093- void onPropertiesChanged(const QVariantMap);
1094-
1095-private:
1096- QString m_mode;
1097- bool m_enabled;
1098- bool m_stored;
1099- QString m_password;
1100- QByteArray m_ssid;
1101- QDBusObjectPath m_device_path;
1102- QDBusObjectPath m_hotspot_path;
1103-
1104- void disable();
1105-
1106- bool destroy(QDBusObjectPath);
1107-
1108- void setStored(bool);
1109- void setEnable(bool);
1110- void updateSettingsFromDbus(QDBusObjectPath);
1111-};
1112-
1113-#endif
1114
1115=== modified file 'plugins/cellular/plugin.cpp'
1116--- plugins/cellular/plugin.cpp 2015-01-21 20:44:20 +0000
1117+++ plugins/cellular/plugin.cpp 2015-07-22 16:28:59 +0000
1118@@ -20,7 +20,6 @@
1119 #include <QtQml>
1120 #include <QtQml/QQmlContext>
1121 #include "connectivity.h"
1122-#include "hotspotmanager.h"
1123 #include "ofonoactivator.h"
1124
1125 static QObject *connectivitySingeltonProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
1126@@ -36,7 +35,6 @@
1127 {
1128 Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Cellular"));
1129 qmlRegisterSingletonType<Connectivity>(uri, 1, 0, "Connectivity", connectivitySingeltonProvider);
1130- qmlRegisterType<HotspotManager>(uri, 1, 0, "HotspotManager");
1131 qmlRegisterType<OfonoActivator>(uri, 1, 0, "OfonoActivator");
1132 }
1133

Subscribers

People subscribed via source and target branches