Merge lp:~pete-woods/indicator-network/connection-manager-improvements into lp:indicator-network

Proposed by Pete Woods
Status: Merged
Approved by: Pete Woods
Approved revision: 654
Merged at revision: 655
Proposed branch: lp:~pete-woods/indicator-network/connection-manager-improvements
Merge into: lp:indicator-network
Diff against target: 515 lines (+165/-150)
8 files modified
src/indicator/nmofono/connection/active-connection-manager.cpp (+56/-1)
src/indicator/nmofono/connection/active-connection-manager.h (+5/-0)
src/indicator/nmofono/ethernet/ethernet-link.cpp (+3/-16)
src/indicator/nmofono/ethernet/ethernet-link.h (+0/-1)
src/indicator/nmofono/hotspot-manager.cpp (+4/-10)
src/indicator/nmofono/manager-impl.cpp (+1/-1)
src/indicator/nmofono/vpn/vpn-manager.cpp (+1/-13)
src/indicator/nmofono/wifi/wifi-link-impl.cpp (+95/-108)
To merge this branch: bzr merge lp:~pete-woods/indicator-network/connection-manager-improvements
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
Xavi Garcia Approve
Review via email: mp+313138@code.launchpad.net

Commit message

Use high-level C++ ActiveConnectionManager class for activating and deactivating connections

- Add activate and deactivate methods to ActiveConnectionManager.
- Improve ActiveConnectionManager so that its state is up to date as soon as activate/deactivate are called.
- Use ActiveConnectionManager across the whole codebase for activating and deactivating connections.

Description of the change

Use high-level C++ ActiveConnectionManager class for activating and deactivating connections

- Add activate and deactivate methods to ActiveConnectionManager.
- Improve ActiveConnectionManager so that its state is up to date as soon as activate/deactivate are called.
- Use ActiveConnectionManager across the whole codebase for activating and deactivating connections.

To post a comment you must log in.
Revision history for this message
Xavi Garcia (xavi-garcia-mena) wrote :

Looks good to me.
In fact the diff looks bigger than it really is.
I don't see anything weird.

I've looked at the code and the full files modified in the branch, but I'm not an expert in indicator-network.

From a point of view of managing the active connections it looks good.
Maybe it would be good to have another pair of eyes on this...

review: Approve
Revision history for this message
Charles Kerr (charlesk) wrote :

LGTM as well. Most of this looks like straightforward consolidation into ACM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/indicator/nmofono/connection/active-connection-manager.cpp'
2--- src/indicator/nmofono/connection/active-connection-manager.cpp 2016-12-01 11:40:00 +0000
3+++ src/indicator/nmofono/connection/active-connection-manager.cpp 2016-12-13 14:49:16 +0000
4@@ -67,6 +67,26 @@
5 }
6 }
7
8+ ActiveConnection::SPtr addConnection(const QDBusObjectPath& path)
9+ {
10+ ActiveConnection::SPtr connection;
11+
12+ auto it = m_connections.constFind(path);
13+ if (it == m_connections.constEnd())
14+ {
15+ connection = make_shared<ActiveConnection>(path, m_manager->connection());
16+ m_connections.insert(path, connection);
17+ Q_EMIT p.connectionsChanged(m_connections.values().toSet());
18+ Q_EMIT p.connectionsUpdated();
19+ }
20+ else
21+ {
22+ connection = *it;
23+ }
24+
25+ return connection;
26+ }
27+
28 public Q_SLOTS:
29 void propertiesChanged(const QVariantMap &properties)
30 {
31@@ -111,7 +131,17 @@
32
33 ActiveConnection::SPtr ActiveConnectionManager::connection(const QDBusObjectPath& path) const
34 {
35- return d->m_connections.value(path);
36+ auto connection = d->m_connections.value(path);
37+ if (path.path() != "/" && !connection)
38+ {
39+ d->updateConnections(d->m_manager->activeConnections());
40+ connection = d->m_connections.value(path);
41+ if (!connection)
42+ {
43+ qWarning() << "Could not find connection at path" << path.path();
44+ }
45+ }
46+ return connection;
47 }
48
49 bool ActiveConnectionManager::deactivate(ActiveConnection::SPtr activeConnection)
50@@ -126,6 +156,31 @@
51 return true;
52 }
53
54+ActiveConnection::SPtr ActiveConnectionManager::activate(const QDBusObjectPath& connection, const QDBusObjectPath& device, const QDBusObjectPath& specificObject)
55+{
56+ auto reply = d->m_manager->ActivateConnection(connection, device, specificObject);
57+ reply.waitForFinished();
58+ if (reply.isError())
59+ {
60+ qWarning() << reply.error().message();
61+ return ActiveConnection::SPtr();
62+ }
63+ return d->addConnection(reply);
64+}
65+
66+
67+ActiveConnection::SPtr ActiveConnectionManager::addAndActivate(const QVariantDictMap &connection, const QDBusObjectPath &device, const QDBusObjectPath &specificObject)
68+{
69+ auto reply = d->m_manager->AddAndActivateConnection(connection, device, specificObject);
70+ reply.waitForFinished();
71+ if (reply.isError())
72+ {
73+ qWarning() << reply.error().message();
74+ return ActiveConnection::SPtr();
75+ }
76+ return d->addConnection(reply.argumentAt<1>());
77+}
78+
79 }
80 }
81
82
83=== modified file 'src/indicator/nmofono/connection/active-connection-manager.h'
84--- src/indicator/nmofono/connection/active-connection-manager.h 2016-12-01 11:40:00 +0000
85+++ src/indicator/nmofono/connection/active-connection-manager.h 2016-12-13 14:49:16 +0000
86@@ -23,6 +23,7 @@
87 #include <QSet>
88
89 #include <nmofono/connection/active-connection.h>
90+#include <dbus-types.h>
91
92 namespace nmofono
93 {
94@@ -46,6 +47,10 @@
95
96 bool deactivate(ActiveConnection::SPtr activeConnection);
97
98+ ActiveConnection::SPtr activate(const QDBusObjectPath& connection, const QDBusObjectPath& device = QDBusObjectPath("/"), const QDBusObjectPath& specificObject = QDBusObjectPath("/"));
99+
100+ ActiveConnection::SPtr addAndActivate(const QVariantDictMap &connection, const QDBusObjectPath &device, const QDBusObjectPath &specificObject);
101+
102 Q_SIGNALS:
103 void connectionsChanged(const QSet<ActiveConnection::SPtr>& connections);
104
105
106=== modified file 'src/indicator/nmofono/ethernet/ethernet-link.cpp'
107--- src/indicator/nmofono/ethernet/ethernet-link.cpp 2016-12-05 11:07:31 +0000
108+++ src/indicator/nmofono/ethernet/ethernet-link.cpp 2016-12-13 14:49:16 +0000
109@@ -211,8 +211,6 @@
110
111 shared_ptr<OrgFreedesktopNetworkManagerDeviceInterface> m_dev;
112
113- shared_ptr<OrgFreedesktopNetworkManagerInterface> m_nm;
114-
115 shared_ptr<OrgFreedesktopNetworkManagerSettingsInterface> m_settings;
116
117 shared_ptr<OrgFreedesktopNetworkManagerDeviceWiredInterface> m_wired;
118@@ -234,11 +232,10 @@
119 bool m_autoConnect = false;
120 };
121
122-EthernetLink::EthernetLink(shared_ptr<OrgFreedesktopNetworkManagerDeviceInterface> dev, shared_ptr<OrgFreedesktopNetworkManagerInterface> nm, shared_ptr<OrgFreedesktopNetworkManagerSettingsInterface> settings, ActiveConnectionManager::SPtr connectionManager) :
123+EthernetLink::EthernetLink(shared_ptr<OrgFreedesktopNetworkManagerDeviceInterface> dev, shared_ptr<OrgFreedesktopNetworkManagerSettingsInterface> settings, ActiveConnectionManager::SPtr connectionManager) :
124 d(new Private(*this))
125 {
126 d->m_dev = dev;
127- d->m_nm = nm;
128 d->m_settings = settings;
129 d->m_connectionManager = connectionManager;
130 d->m_devicePropertyCache = make_shared<util::DBusPropertyCache>(NM_DBUS_SERVICE, NM_DBUS_INTERFACE_DEVICE, dev->path(), dev->connection());
131@@ -321,12 +318,7 @@
132 {
133 if (d->m_preferredConnection)
134 {
135- auto reply = d->m_nm->ActivateConnection(d->m_preferredConnection->path(), QDBusObjectPath(d->m_dev->path()), QDBusObjectPath("/"));
136- reply.waitForFinished();
137- if (reply.isError())
138- {
139- qWarning() << reply.error().message();
140- }
141+ d->m_connectionManager->activate(d->m_preferredConnection->path(), QDBusObjectPath(d->m_dev->path()));
142 }
143 d->m_dev->setAutoconnect(true);
144 }
145@@ -356,12 +348,7 @@
146
147 if (d->m_autoConnect && preferredConnection)
148 {
149- auto reply = d->m_nm->ActivateConnection(d->m_preferredConnection->path(), QDBusObjectPath(d->m_dev->path()), QDBusObjectPath("/"));
150- reply.waitForFinished();
151- if (reply.isError())
152- {
153- qWarning() << reply.error().message();
154- }
155+ d->m_connectionManager->activate(d->m_preferredConnection->path(), QDBusObjectPath(d->m_dev->path()));
156 }
157
158 Q_EMIT preferredConnectionChanged(preferredConnection);
159
160=== modified file 'src/indicator/nmofono/ethernet/ethernet-link.h'
161--- src/indicator/nmofono/ethernet/ethernet-link.h 2016-12-01 11:40:00 +0000
162+++ src/indicator/nmofono/ethernet/ethernet-link.h 2016-12-13 14:49:16 +0000
163@@ -46,7 +46,6 @@
164 UNITY_DEFINES_PTRS(EthernetLink);
165
166 EthernetLink(std::shared_ptr<OrgFreedesktopNetworkManagerDeviceInterface> dev,
167- std::shared_ptr<OrgFreedesktopNetworkManagerInterface> nm,
168 std::shared_ptr<OrgFreedesktopNetworkManagerSettingsInterface> settings,
169 nmofono::connection::ActiveConnectionManager::SPtr connectionManager);
170
171
172=== modified file 'src/indicator/nmofono/hotspot-manager.cpp'
173--- src/indicator/nmofono/hotspot-manager.cpp 2016-05-26 13:51:39 +0000
174+++ src/indicator/nmofono/hotspot-manager.cpp 2016-12-13 14:49:16 +0000
175@@ -108,21 +108,15 @@
176
177 bool activateConnection(const QDBusObjectPath& device)
178 {
179- auto reply = m_manager->ActivateConnection(
180- QDBusObjectPath(m_hotspot->path()), device,
181- QDBusObjectPath("/"));
182- reply.waitForFinished();
183- if (reply.isError())
184+ auto activeConnectionObject = m_activeConnectionManager->activate(QDBusObjectPath(m_hotspot->path()), device);
185+ if (!activeConnectionObject)
186 {
187- qCritical() << "Could not activate hotspot connection"
188- << reply.error().message();
189+ qCritical() << "Could not activate hotspot connection";
190 return false;
191 }
192
193- QDBusObjectPath activeConnectionPath(reply);
194-
195 OrgFreedesktopNetworkManagerConnectionActiveInterface activeConnection (
196- NM_DBUS_SERVICE, activeConnectionPath.path (),
197+ NM_DBUS_SERVICE, activeConnectionObject->path().path (),
198 m_manager->connection());
199
200 int count = 0;
201
202=== modified file 'src/indicator/nmofono/manager-impl.cpp'
203--- src/indicator/nmofono/manager-impl.cpp 2016-12-01 11:40:00 +0000
204+++ src/indicator/nmofono/manager-impl.cpp 2016-12-13 14:49:16 +0000
205@@ -784,7 +784,7 @@
206 case NM_DEVICE_TYPE_ETHERNET:
207 {
208 link = make_shared<ethernet::EthernetLink>(
209- dev, d->nm, d->m_settingsInterface, d->m_activeConnectionManager);
210+ dev, d->m_settingsInterface, d->m_activeConnectionManager);
211 break;
212 }
213 case NM_DEVICE_TYPE_MODEM:
214
215=== modified file 'src/indicator/nmofono/vpn/vpn-manager.cpp'
216--- src/indicator/nmofono/vpn/vpn-manager.cpp 2016-05-26 13:51:39 +0000
217+++ src/indicator/nmofono/vpn/vpn-manager.cpp 2016-12-13 14:49:16 +0000
218@@ -112,19 +112,7 @@
219
220 void activateConnection(const QDBusObjectPath& connection)
221 {
222- auto reply = m_nmInterface->ActivateConnection(connection, QDBusObjectPath("/"), QDBusObjectPath("/"));
223- auto watcher(new QDBusPendingCallWatcher(reply, this));
224- connect(watcher, &QDBusPendingCallWatcher::finished, this, &Priv::activateConnectionFinished);
225- }
226-
227- void activateConnectionFinished(QDBusPendingCallWatcher *call)
228- {
229- QDBusPendingReply<QDBusObjectPath> reply = *call;
230- if (reply.isError())
231- {
232- qWarning() << reply.error().message();
233- }
234- call->deleteLater();
235+ m_activeConnectionManager->activate(connection);
236 }
237
238 void updateActiveAndBusy()
239
240=== modified file 'src/indicator/nmofono/wifi/wifi-link-impl.cpp'
241--- src/indicator/nmofono/wifi/wifi-link-impl.cpp 2016-12-01 11:40:00 +0000
242+++ src/indicator/nmofono/wifi/wifi-link-impl.cpp 2016-12-13 14:49:16 +0000
243@@ -108,7 +108,7 @@
244 case NM_DEVICE_STATE_FAILED:
245 {
246 // make sure to set activeConnection before changing the status
247- updateActiveConnection(QDBusObjectPath("/"));
248+ updateActiveConnection(connection::ActiveConnection::SPtr());
249
250 switch(m_killSwitch->state()) {
251 case KillSwitch::State::hard_blocked:
252@@ -134,7 +134,7 @@
253 // we have one.
254 if (path != QDBusObjectPath("/"))
255 {
256- updateActiveConnection(path);
257+ updateActiveConnection(m_activeConnectionManager->connection(path));
258 }
259 setStatus(Status::connecting);
260 break;
261@@ -142,21 +142,20 @@
262 case NM_DEVICE_STATE_SECONDARIES:
263 {
264 // make sure to set activeConnection before changing the status
265- updateActiveConnection(m_dev->activeConnection());
266+ updateActiveConnection(m_activeConnectionManager->connection(m_dev->activeConnection()));
267 setStatus(Status::connected);
268 break;
269 }
270 case NM_DEVICE_STATE_ACTIVATED:
271 {
272 // make sure to set activeConnection before changing the status
273- updateActiveConnection(m_dev->activeConnection());
274+ updateActiveConnection(m_activeConnectionManager->connection(m_dev->activeConnection()));
275 setStatus(Status::online);
276 break;
277 }}
278
279 }
280
281-
282 void disconnectSignalStengthConnection()
283 {
284 if (m_signalStrengthConnection)
285@@ -166,11 +165,10 @@
286 }
287 }
288
289- /// '/' path means invalid.
290- void updateActiveConnection(const QDBusObjectPath &path)
291+ void updateActiveConnection(connection::ActiveConnection::SPtr activeConnection)
292 {
293 // clear the one we have.
294- if (path == QDBusObjectPath("/")) {
295+ if (!activeConnection) {
296 m_activeAccessPoint.reset();
297 Q_EMIT p.activeAccessPointUpdated(m_activeAccessPoint);
298 m_activeConnection.reset();
299@@ -180,45 +178,38 @@
300 }
301
302 // already up-to-date
303- if (m_activeConnection && m_activeConnection->path() == path)
304+ if (m_activeConnection && m_activeConnection->path() == activeConnection->path())
305 {
306 return;
307 }
308
309- m_activeConnection = m_activeConnectionManager->connection(path);
310- if (m_activeConnection)
311- {
312- auto state = m_activeConnection->state();
313- switch (state) {
314- case connection::ActiveConnection::State::unknown:
315- case connection::ActiveConnection::State::activating:
316- case connection::ActiveConnection::State::activated:
317- case connection::ActiveConnection::State::deactivating:
318- case connection::ActiveConnection::State::deactivated:
319- // for Wi-Fi devices specific_object is the AccessPoint object.
320- QDBusObjectPath ap_path = m_activeConnection->specificObject();
321- for (auto &ap : m_groupedAccessPoints) {
322- auto shap = dynamic_pointer_cast<GroupedAccessPoint>(ap);
323- if (shap->has_object(ap_path)) {
324- m_activeAccessPoint = ap;
325- disconnectSignalStengthConnection();
326- m_signalStrengthConnection = make_unique<
327- QMetaObject::Connection>(
328- connect(m_activeAccessPoint.get(),
329- &AccessPoint::strengthUpdated, this,
330- &Private::strengthUpdated));
331- Q_EMIT p.activeAccessPointUpdated(m_activeAccessPoint);
332- strengthUpdated();
333- break;
334- }
335+ m_activeConnection = activeConnection;
336+ auto state = m_activeConnection->state();
337+ switch (state) {
338+ case connection::ActiveConnection::State::unknown:
339+ case connection::ActiveConnection::State::activating:
340+ case connection::ActiveConnection::State::activated:
341+ case connection::ActiveConnection::State::deactivating:
342+ case connection::ActiveConnection::State::deactivated:
343+ // for Wi-Fi devices specific_object is the AccessPoint object.
344+ QDBusObjectPath ap_path = m_activeConnection->specificObject();
345+ for (auto &ap : m_groupedAccessPoints) {
346+ auto shap = dynamic_pointer_cast<GroupedAccessPoint>(ap);
347+ if (shap->has_object(ap_path)) {
348+ m_activeAccessPoint = ap;
349+ disconnectSignalStengthConnection();
350+ m_signalStrengthConnection = make_unique<
351+ QMetaObject::Connection>(
352+ connect(m_activeAccessPoint.get(),
353+ &AccessPoint::strengthUpdated, this,
354+ &Private::strengthUpdated));
355+ Q_EMIT p.activeAccessPointUpdated(m_activeAccessPoint);
356+ strengthUpdated();
357+ break;
358 }
359 }
360 }
361- else
362- {
363- qWarning() << "Failed to get active connection:" << path.path();
364- }
365- }
366+}
367
368
369 public Q_SLOTS:
370@@ -450,81 +441,77 @@
371 {
372 qDebug() << "Connecting to:" << accessPoint->ssid();
373
374- try {
375- d->m_connecting = true;
376- QByteArray ssid = accessPoint->raw_ssid();
377+ d->m_connecting = true;
378+ QByteArray ssid = accessPoint->raw_ssid();
379
380- shared_ptr<OrgFreedesktopNetworkManagerSettingsConnectionInterface> found;
381- QList<QDBusObjectPath> connections = d->m_dev->availableConnections();
382- for (auto &path : connections) {
383- auto con = make_shared<OrgFreedesktopNetworkManagerSettingsConnectionInterface>(
384- NM_DBUS_SERVICE, path.path(), d->m_dev->connection());
385- QVariantDictMap settings = con->GetSettings();
386- auto wirelessIt = settings.find("802-11-wireless");
387- if (wirelessIt != settings.cend())
388+ shared_ptr<OrgFreedesktopNetworkManagerSettingsConnectionInterface> found;
389+ QList<QDBusObjectPath> connections = d->m_dev->availableConnections();
390+ for (auto &path : connections) {
391+ auto con = make_shared<OrgFreedesktopNetworkManagerSettingsConnectionInterface>(
392+ NM_DBUS_SERVICE, path.path(), d->m_dev->connection());
393+ QVariantDictMap settings = con->GetSettings();
394+ auto wirelessIt = settings.find("802-11-wireless");
395+ if (wirelessIt != settings.cend())
396+ {
397+ auto ssidIt = wirelessIt->find("ssid");
398+ if (ssidIt != wirelessIt->cend())
399 {
400- auto ssidIt = wirelessIt->find("ssid");
401- if (ssidIt != wirelessIt->cend())
402+ if (ssidIt->toByteArray() == ssid)
403 {
404- if (ssidIt->toByteArray() == ssid)
405- {
406- found = con;
407- break;
408- }
409+ found = con;
410+ break;
411 }
412 }
413 }
414-
415- /// @todo check the timestamps as there might be multiple ones that are suitable.
416- /// @todo oh, and check more parameters than just the ssid
417-
418- QDBusObjectPath ac("/");
419- if (found) {
420- qDebug() << "Connecting to known access point";
421- ac = d->m_nm->ActivateConnection(QDBusObjectPath(found->path()),
422- QDBusObjectPath(d->m_dev->path()),
423- accessPoint->object_path());
424+ }
425+
426+ /// @todo check the timestamps as there might be multiple ones that are suitable.
427+ /// @todo oh, and check more parameters than just the ssid
428+
429+ connection::ActiveConnection::SPtr ac;
430+ if (found) {
431+ qDebug() << "Connecting to known access point";
432+ ac = d->m_activeConnectionManager->activate(QDBusObjectPath(found->path()),
433+ QDBusObjectPath(d->m_dev->path()),
434+ accessPoint->object_path());
435+ } else {
436+ if (accessPoint->enterprise()) {
437+ qDebug() << "New connection to enterprise access point";
438+ // activate system settings URI
439+ QUrlQuery q;
440+ q.addQueryItem("ssid", accessPoint->raw_ssid());
441+ q.addQueryItem("bssid", accessPoint->bssid());
442+ QString url = "settings:///system/wifi?" + q.query(QUrl::FullyEncoded);
443+
444+ UrlDispatcher::send(url.toStdString(), [](string url, bool success) {
445+ if (!success) {
446+ cerr << "URL Dispatcher failed on " << url << endl;
447+ }
448+ });
449 } else {
450- if (accessPoint->enterprise()) {
451- qDebug() << "New connection to enterprise access point";
452- // activate system settings URI
453- QUrlQuery q;
454- q.addQueryItem("ssid", accessPoint->raw_ssid());
455- q.addQueryItem("bssid", accessPoint->bssid());
456- QString url = "settings:///system/wifi?" + q.query(QUrl::FullyEncoded);
457-
458- UrlDispatcher::send(url.toStdString(), [](string url, bool success) {
459- if (!success) {
460- cerr << "URL Dispatcher failed on " << url << endl;
461- }
462- });
463- } else {
464- qDebug() << "New connection to regular access point";
465- QVariantDictMap conf;
466-
467- /// @todo getting the ssid multiple times over dbus is stupid.
468-
469- QVariantMap wireless_conf;
470- wireless_conf["ssid"] = ssid;
471-
472- conf["802-11-wireless"] = wireless_conf;
473- auto ret = d->m_nm->AddAndActivateConnection(
474- conf, QDBusObjectPath(d->m_dev->path()), accessPoint->object_path());
475- ret.waitForFinished();
476- ac = ret.argumentAt<1>();
477- }
478- }
479- // For enterprise access points, the system settings app will perform the connection
480- if (!accessPoint->enterprise()) {
481- d->updateActiveConnection(ac);
482- }
483- d->m_connecting = false;
484- } catch(const exception &e) {
485- // @bug default timeout expired: LP(#1361642)
486- // If this happens, indicator-network is in an unknown state with no clear way of
487- // recovering. The only reasonable way out is a graceful exit.
488- qWarning() << " Failed to activate connection: " << e.what();
489- }
490+ qDebug() << "New connection to regular access point";
491+ QVariantDictMap conf;
492+
493+ /// @todo getting the ssid multiple times over dbus is stupid.
494+
495+ QVariantMap wireless_conf;
496+ wireless_conf["ssid"] = ssid;
497+
498+ conf["802-11-wireless"] = wireless_conf;
499+ ac = d->m_activeConnectionManager->addAndActivate(conf, QDBusObjectPath(d->m_dev->path()), accessPoint->object_path());
500+ }
501+ }
502+ if (!ac)
503+ {
504+ qWarning() << " Failed to activate connection";
505+ return;
506+ }
507+
508+ // For enterprise access points, the system settings app will perform the connection
509+ if (!accessPoint->enterprise()) {
510+ d->updateActiveConnection(ac);
511+ }
512+ d->m_connecting = false;
513 }
514
515 AccessPoint::Ptr

Subscribers

People subscribed via source and target branches