Merge lp:~pete-woods/indicator-network/simplify-toggles into lp:indicator-network/15.10

Proposed by Pete Woods
Status: Merged
Approved by: Pete Woods
Approved revision: 519
Merged at revision: 505
Proposed branch: lp:~pete-woods/indicator-network/simplify-toggles
Merge into: lp:indicator-network/15.10
Prerequisite: lp:~pete-woods/indicator-network/wakelock-on-hotspot-active
Diff against target: 616 lines (+167/-201) (has conflicts)
12 files modified
src/indicator/connectivity-service/connectivity-service.cpp (+15/-16)
src/indicator/nmofono/hotspot-manager.h (+2/-2)
src/indicator/nmofono/kill-switch.cpp (+28/-21)
src/indicator/nmofono/kill-switch.h (+1/-24)
src/indicator/nmofono/link.h (+0/-6)
src/indicator/nmofono/manager-impl.cpp (+67/-43)
src/indicator/nmofono/manager-impl.h (+18/-2)
src/indicator/nmofono/manager.h (+36/-3)
src/indicator/nmofono/wifi/wifi-link-impl.cpp (+0/-67)
src/indicator/nmofono/wifi/wifi-link-impl.h (+0/-3)
src/indicator/nmofono/wwan/modem.cpp (+0/-10)
src/indicator/nmofono/wwan/modem.h (+0/-4)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~pete-woods/indicator-network/simplify-toggles
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Indicator Applet Developers Pending
Review via email: mp+267052@code.launchpad.net

Commit message

Simplify wifi/flight toggles

Description of the change

Simplify wifi/flight toggles

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/indicator/connectivity-service/connectivity-service.cpp'
2--- src/indicator/connectivity-service/connectivity-service.cpp 2015-08-05 15:22:19 +0000
3+++ src/indicator/connectivity-service/connectivity-service.cpp 2015-08-05 15:22:19 +0000
4@@ -197,14 +197,13 @@
5 connect(d->m_manager.get(), &Manager::wifiEnabledUpdated, d.get(), &Private::wifiEnabledUpdated);
6 connect(d->m_manager.get(), &Manager::unstoppableOperationHappeningUpdated, d.get(), &Private::unstoppableOperationHappeningUpdated);
7
8- auto hotspotManager = d->m_manager->hotspotManager();
9- connect(hotspotManager.get(), &HotspotManager::enabledChanged, d.get(), &Private::hotspotEnabledUpdated);
10- connect(hotspotManager.get(), &HotspotManager::ssidChanged, d.get(), &Private::hotspotSsidUpdated);
11- connect(hotspotManager.get(), &HotspotManager::passwordChanged, d.get(), &Private::hotspotPasswordUpdated);
12- connect(hotspotManager.get(), &HotspotManager::modeChanged, d.get(), &Private::hotspotModeUpdated);
13- connect(hotspotManager.get(), &HotspotManager::storedChanged, d.get(), &Private::hotspotStoredUpdated);
14+ connect(d->m_manager.get(), &Manager::hotspotEnabledChanged, d.get(), &Private::hotspotEnabledUpdated);
15+ connect(d->m_manager.get(), &Manager::hotspotSsidChanged, d.get(), &Private::hotspotSsidUpdated);
16+ connect(d->m_manager.get(), &Manager::hotspotPasswordChanged, d.get(), &Private::hotspotPasswordUpdated);
17+ connect(d->m_manager.get(), &Manager::hotspotModeChanged, d.get(), &Private::hotspotModeUpdated);
18+ connect(d->m_manager.get(), &Manager::hotspotStoredChanged, d.get(), &Private::hotspotStoredUpdated);
19
20- connect(hotspotManager.get(), &HotspotManager::reportError, d->m_privateService.get(), &PrivateService::ReportError);
21+ connect(d->m_manager.get(), &Manager::reportError, d->m_privateService.get(), &PrivateService::ReportError);
22
23 d->updateNetworkingStatus();
24
25@@ -257,22 +256,22 @@
26
27 bool ConnectivityService::hotspotEnabled() const
28 {
29- return d->m_manager->hotspotManager()->enabled();
30+ return d->m_manager->hotspotEnabled();
31 }
32
33 QByteArray ConnectivityService::hotspotSsid() const
34 {
35- return d->m_manager->hotspotManager()->ssid();
36+ return d->m_manager->hotspotSsid();
37 }
38
39 QString ConnectivityService::hotspotMode() const
40 {
41- return d->m_manager->hotspotManager()->mode();
42+ return d->m_manager->hotspotMode();
43 }
44
45 bool ConnectivityService::hotspotStored() const
46 {
47- return d->m_manager->hotspotManager()->stored();
48+ return d->m_manager->hotspotStored();
49 }
50
51 PrivateService::PrivateService(ConnectivityService& parent) :
52@@ -304,27 +303,27 @@
53
54 void PrivateService::SetHotspotEnabled(bool enabled)
55 {
56- p.d->m_manager->hotspotManager()->setEnabled(enabled);
57+ p.d->m_manager->setHotspotEnabled(enabled);
58 }
59
60 void PrivateService::SetHotspotSsid(const QByteArray &ssid)
61 {
62- p.d->m_manager->hotspotManager()->setSsid(ssid);
63+ p.d->m_manager->setHotspotSsid(ssid);
64 }
65
66 void PrivateService::SetHotspotPassword(const QString &password)
67 {
68- p.d->m_manager->hotspotManager()->setPassword(password);
69+ p.d->m_manager->setHotspotPassword(password);
70 }
71
72 void PrivateService::SetHotspotMode(const QString &mode)
73 {
74- p.d->m_manager->hotspotManager()->setMode(mode);
75+ p.d->m_manager->setHotspotMode(mode);
76 }
77
78 QString PrivateService::hotspotPassword() const
79 {
80- return p.d->m_manager->hotspotManager()->password();
81+ return p.d->m_manager->hotspotPassword();
82 }
83
84 }
85
86=== modified file 'src/indicator/nmofono/hotspot-manager.h'
87--- src/indicator/nmofono/hotspot-manager.h 2015-08-05 15:22:19 +0000
88+++ src/indicator/nmofono/hotspot-manager.h 2015-08-05 15:22:19 +0000
89@@ -123,8 +123,6 @@
90
91 bool enabled() const;
92
93- void setEnabled(bool);
94-
95 bool stored() const;
96
97 QByteArray ssid() const;
98@@ -155,6 +153,8 @@
99 void reportError(int reason);
100
101 public Q_SLOTS:
102+ void setEnabled(bool);
103+
104 void setSsid(const QByteArray&);
105
106 void setPassword(const QString&);
107
108=== modified file 'src/indicator/nmofono/kill-switch.cpp'
109--- src/indicator/nmofono/kill-switch.cpp 2015-04-23 13:22:55 +0000
110+++ src/indicator/nmofono/kill-switch.cpp 2015-08-05 15:22:19 +0000
111@@ -88,27 +88,34 @@
112 }
113
114 void
115-KillSwitch::block()
116-{
117- if (state() == KillSwitch::State::hard_blocked)
118- throw KillSwitch::exception::HardBlocked();
119-
120- try {
121- if (!utils::getOrThrow(d->urfkill->Block(static_cast<uint>(Private::DeviceType::wlan), true)))
122- throw KillSwitch::exception::Failed("Failed to block killswitch");
123- } catch (std::exception &e) {
124- throw KillSwitch::exception::Failed(e.what());
125- }
126-}
127-
128-void
129-KillSwitch::unblock()
130-{
131- try {
132- if (!utils::getOrThrow(d->urfkill->Block(static_cast<uint>(Private::DeviceType::wlan), false)))
133- throw KillSwitch::exception::Failed("Failed to unblock killswitch");
134- } catch (std::exception &e) {
135- throw KillSwitch::exception::Failed(e.what());
136+KillSwitch::setBlock(bool block)
137+{
138+ if (!block && state() == State::hard_blocked)
139+ {
140+ qCritical() << __PRETTY_FUNCTION__ << "Killswitch is hard blocked.";
141+ return;
142+ }
143+
144+ if (!block && state() != State::soft_blocked)
145+ {
146+ return;
147+ }
148+
149+ if (block && state() != State::unblocked)
150+ {
151+ return;
152+ }
153+
154+ try
155+ {
156+ if (!utils::getOrThrow(d->urfkill->Block(static_cast<uint>(Private::DeviceType::wlan), block)))
157+ {
158+ throw std::runtime_error("Failed to block killswitch");
159+ }
160+ }
161+ catch (std::exception &e)
162+ {
163+ qCritical() << __PRETTY_FUNCTION__ << e.what();
164 }
165 }
166
167
168=== modified file 'src/indicator/nmofono/kill-switch.h'
169--- src/indicator/nmofono/kill-switch.h 2015-04-14 11:20:17 +0000
170+++ src/indicator/nmofono/kill-switch.h 2015-08-05 15:22:19 +0000
171@@ -37,24 +37,6 @@
172 public:
173 typedef std::shared_ptr<KillSwitch> Ptr;
174
175- struct exception
176- {
177- struct HardBlocked : public std::runtime_error
178- {
179- HardBlocked()
180- : std::runtime_error("Killswitch is hard blocked.")
181- {}
182- };
183-
184- struct Failed : public std::runtime_error
185- {
186- Failed() = delete;
187- Failed(std::string what)
188- : std::runtime_error(what)
189- {}
190- };
191- };
192-
193 enum class State
194 {
195 not_available = -1,
196@@ -68,12 +50,7 @@
197 KillSwitch(const QDBusConnection& systemBus);
198 ~KillSwitch();
199
200- /// @throws exception::Failed if the switch fails to block
201- void block();
202-
203- /// @throws exception::HardBlocked if trying to unblock when switch is hard blocked
204- /// @throws exception::Failed if the switch fails to unblock
205- void unblock();
206+ void setBlock(bool block);
207
208 State state() const;
209 bool flightMode(bool enable);
210
211=== modified file 'src/indicator/nmofono/link.h'
212--- src/indicator/nmofono/link.h 2015-04-14 11:20:17 +0000
213+++ src/indicator/nmofono/link.h 2015-08-05 15:22:19 +0000
214@@ -92,12 +92,6 @@
215 };
216
217 /// @private
218- virtual void enable() = 0;
219-
220- /// @private
221- virtual void disable() = 0;
222-
223- /// @private
224 virtual Type type() const = 0;
225
226 /// @private
227
228=== modified file 'src/indicator/nmofono/manager-impl.cpp'
229--- src/indicator/nmofono/manager-impl.cpp 2015-08-05 15:22:19 +0000
230+++ src/indicator/nmofono/manager-impl.cpp 2015-08-05 15:22:19 +0000
231@@ -244,6 +244,13 @@
232 connect(d->m_killSwitch.get(), &KillSwitch::stateChanged, d.get(), &Private::updateHasWifi);
233
234 d->m_hotspotManager = make_shared<HotspotManager>(systemConnection);
235+ connect(d->m_hotspotManager.get(), &HotspotManager::enabledChanged, this, &Manager::hotspotEnabledChanged);
236+ connect(d->m_hotspotManager.get(), &HotspotManager::ssidChanged, this, &Manager::hotspotSsidChanged);
237+ connect(d->m_hotspotManager.get(), &HotspotManager::passwordChanged, this, &Manager::hotspotPasswordChanged);
238+ connect(d->m_hotspotManager.get(), &HotspotManager::modeChanged, this, &Manager::hotspotModeChanged);
239+ connect(d->m_hotspotManager.get(), &HotspotManager::storedChanged, this, &Manager::hotspotStoredChanged);
240+
241+ connect(d->m_hotspotManager.get(), &HotspotManager::reportError, this, &Manager::reportError);
242
243 connect(d->nm.get(), &OrgFreedesktopNetworkManagerInterface::DeviceAdded, this, &ManagerImpl::device_added);
244 QList<QDBusObjectPath> devices(d->nm->GetDevices());
245@@ -256,16 +263,7 @@
246 connect(d->nm.get(), &OrgFreedesktopNetworkManagerInterface::PropertiesChanged, this, &ManagerImpl::nm_properties_changed);
247
248 connect(d->m_killSwitch.get(), &KillSwitch::flightModeChanged, d.get(), &Private::setFlightMode);
249- try
250- {
251- d->setFlightMode(d->m_killSwitch->isFlightMode());
252- }
253- catch (exception const& e)
254- {
255- cerr << __PRETTY_FUNCTION__ << ": " << e.what() << endl;
256- cerr << "Failed to retrieve initial flight mode state, assuming state is false." << endl;
257- d->setFlightMode(false);
258- }
259+ d->setFlightMode(d->m_killSwitch->isFlightMode());
260
261 /// @todo set by the default connections.
262 d->m_characteristics = Link::Characteristics::empty;
263@@ -418,48 +416,23 @@
264 }
265
266
267-bool
268+void
269 ManagerImpl::setWifiEnabled(bool enabled)
270 {
271 if (!d->m_hasWifi)
272 {
273- return false;
274+ return;
275 }
276
277 if (d->m_wifiEnabled == enabled)
278 {
279- return false;
280+ return;
281 }
282
283- bool success = true;
284 d->setUnstoppableOperationHappening(true);
285-
286- try
287- {
288- if (enabled)
289- {
290- if (d->m_killSwitch->state() == KillSwitch::State::soft_blocked)
291- {
292- // try to unblock. throws if fails.
293- d->m_killSwitch->unblock();
294- }
295- }
296- else
297- {
298- if (d->m_killSwitch->state() == KillSwitch::State::unblocked) {
299- // block the device. that will disable it also
300- d->m_killSwitch->block();
301- }
302- }
303- d->nm->setWirelessEnabled(enabled);
304- }
305- catch (runtime_error &e)
306- {
307- qWarning() << __PRETTY_FUNCTION__ << ": " << e.what();
308- success = false;
309- }
310+ d->m_killSwitch->setBlock(!enabled);
311+ d->nm->setWirelessEnabled(enabled);
312 d->setUnstoppableOperationHappening(false);
313- return success;
314 }
315
316 bool
317@@ -557,9 +530,60 @@
318 return d->m_ofonoLinks.values().toSet();
319 }
320
321-HotspotManager::SPtr ManagerImpl::hotspotManager() const
322-{
323- return d->m_hotspotManager;
324+bool
325+ManagerImpl::hotspotEnabled() const
326+{
327+ return d->m_hotspotManager->enabled();
328+}
329+
330+bool
331+ManagerImpl::hotspotStored() const
332+{
333+ return d->m_hotspotManager->stored();
334+}
335+
336+QByteArray
337+ManagerImpl::hotspotSsid() const
338+{
339+ return d->m_hotspotManager->ssid();
340+}
341+
342+QString
343+ManagerImpl::hotspotPassword() const
344+{
345+ return d->m_hotspotManager->password();
346+}
347+
348+QString
349+ManagerImpl::hotspotMode() const
350+{
351+ return d->m_hotspotManager->mode();
352+}
353+
354+void
355+ManagerImpl::setHotspotEnabled(bool enabled)
356+{
357+ d->setUnstoppableOperationHappening(true);
358+ d->m_hotspotManager->setEnabled(enabled);
359+ d->setUnstoppableOperationHappening(false);
360+}
361+
362+void
363+ManagerImpl::setHotspotSsid(const QByteArray& ssid)
364+{
365+ d->m_hotspotManager->setSsid(ssid);
366+}
367+
368+void
369+ManagerImpl::setHotspotPassword(const QString& password)
370+{
371+ d->m_hotspotManager->setPassword(password);
372+}
373+
374+void
375+ManagerImpl::setHotspotMode(const QString& mode)
376+{
377+ d->m_hotspotManager->setMode(mode);
378 }
379
380 }
381
382=== modified file 'src/indicator/nmofono/manager-impl.h'
383--- src/indicator/nmofono/manager-impl.h 2015-08-05 15:22:19 +0000
384+++ src/indicator/nmofono/manager-impl.h 2015-08-05 15:22:19 +0000
385@@ -51,7 +51,7 @@
386 bool hasWifi() const override;
387 bool wifiEnabled() const override;
388
389- bool setWifiEnabled(bool) override;
390+ void setWifiEnabled(bool) override;
391
392 bool roaming() const override;
393
394@@ -66,7 +66,23 @@
395 void unlockAllModems() override;
396 void unlockModemByName(const QString &name) override;
397
398- HotspotManager::SPtr hotspotManager() const;
399+ bool hotspotEnabled() const override;
400+
401+ bool hotspotStored() const override;
402+
403+ QByteArray hotspotSsid() const override;
404+
405+ QString hotspotPassword() const override;
406+
407+ QString hotspotMode() const override;
408+
409+ void setHotspotEnabled(bool) override;
410+
411+ void setHotspotSsid(const QByteArray&) override;
412+
413+ void setHotspotPassword(const QString&) override;
414+
415+ void setHotspotMode(const QString&) override;
416
417 private Q_SLOTS:
418 void device_added(const QDBusObjectPath &path);
419
420=== modified file 'src/indicator/nmofono/manager.h'
421--- src/indicator/nmofono/manager.h 2015-08-05 15:22:19 +0000
422+++ src/indicator/nmofono/manager.h 2015-08-05 15:22:19 +0000
423@@ -87,8 +87,6 @@
424 Q_PROPERTY(bool unstoppableOperationHappening READ unstoppableOperationHappening NOTIFY unstoppableOperationHappeningUpdated)
425 virtual bool unstoppableOperationHappening() const = 0;
426
427- virtual HotspotManager::SPtr hotspotManager() const = 0;
428-
429 /// @private
430 Q_PROPERTY(QSet<Link::Ptr> links READ links NOTIFY linksUpdated)
431 virtual QSet<Link::Ptr> links() const = 0;
432@@ -130,6 +128,21 @@
433
434 virtual void unlockModemByName(const QString &name) = 0;
435
436+ Q_PROPERTY(bool hotspotEnabled READ hotspotEnabled WRITE setHotspotEnabled NOTIFY hotspotEnabledChanged)
437+ virtual bool hotspotEnabled() const = 0;
438+
439+ Q_PROPERTY(bool hotspotStored READ hotspotStored NOTIFY hotspotStoredChanged)
440+ virtual bool hotspotStored() const = 0;
441+
442+ Q_PROPERTY(QByteArray hotspotSsid READ hotspotSsid WRITE setHotspotSsid NOTIFY hotspotSsidChanged)
443+ virtual QByteArray hotspotSsid() const = 0;
444+
445+ Q_PROPERTY(QString hotspotPassword READ hotspotPassword WRITE setHotspotPassword NOTIFY hotspotPasswordChanged)
446+ virtual QString hotspotPassword() const = 0;
447+
448+ Q_PROPERTY(QString hotspotMode READ hotspotMode WRITE setHotspotMode NOTIFY hotspotModeChanged)
449+ virtual QString hotspotMode() const = 0;
450+
451 Q_SIGNALS:
452 void flightModeUpdated(FlightModeStatus);
453
454@@ -143,13 +156,33 @@
455
456 void wifiEnabledUpdated(bool);
457
458+ void hotspotEnabledChanged(bool enabled);
459+
460+ void hotspotStoredChanged(bool stored);
461+
462+ void hotspotSsidChanged(const QByteArray& ssid);
463+
464+ void hotspotPasswordChanged(const QString& password);
465+
466+ void hotspotModeChanged(const QString& mode);
467+
468+ void reportError(int reason);
469+
470 void unstoppableOperationHappeningUpdated(bool);
471
472 public Q_SLOTS:
473- virtual bool setWifiEnabled(bool) = 0;
474+ virtual void setWifiEnabled(bool) = 0;
475
476 virtual void setFlightMode(bool) = 0;
477
478+ virtual void setHotspotEnabled(bool) = 0;
479+
480+ virtual void setHotspotSsid(const QByteArray&) = 0;
481+
482+ virtual void setHotspotPassword(const QString&) = 0;
483+
484+ virtual void setHotspotMode(const QString&) = 0;
485+
486 protected:
487 /**
488 * @brief The default constructor is protected.
489
490=== modified file 'src/indicator/nmofono/wifi/wifi-link-impl.cpp'
491--- src/indicator/nmofono/wifi/wifi-link-impl.cpp 2015-07-08 08:49:30 +0000
492+++ src/indicator/nmofono/wifi/wifi-link-impl.cpp 2015-08-05 15:22:19 +0000
493@@ -316,73 +316,6 @@
494 WifiLinkImpl::~WifiLinkImpl()
495 {}
496
497-void
498-WifiLinkImpl::enable()
499-{
500-#ifdef INDICATOR_NETWORK_TRACE_MESSAGES
501- qDebug() << __PRETTY_FUNCTION__;
502-#endif
503-
504- try {
505- if (d->m_killSwitch->state() != KillSwitch::State::unblocked) {
506- // try to unblock. throws if fails.
507- d->m_killSwitch->unblock();
508- }
509- d->m_nm->setWirelessEnabled(true);
510- d->m_dev->setAutoconnect(true);
511- } catch(runtime_error &e) {
512- /// @todo when toggling enable()/disable() rapidly the default timeout of
513- /// 1 second in dbus::core::Property is not long enough..
514- /// just ignore for now and get dbus-cpp to have larger timeout.
515- cerr << __PRETTY_FUNCTION__ << ": " << e.what() << endl;
516- }
517-
518-#if 0
519- /** @todo:
520- * NetworkManager 0.9.9 allows doing this below and letting NM to figure out the best connection:
521- *
522- * m_nm.activate_connection(dbus::types::ObjectPath("/"),
523- * m_dev.object->path(),
524- * core::dbus::typ es::ObjectPath("/"));
525- *
526- * for now we get somewhat similar result by toggling the Autoconnect property,
527- * but this breaks the possible setting we will have for autoconnecting later.
528- */
529- m_dev.autoconnect->set(true);
530- m_disabled = false;
531-#endif
532-}
533-
534-void
535-WifiLinkImpl::disable()
536-{
537-#ifdef INDICATOR_NETWORK_TRACE_MESSAGES
538- cout << __PRETTY_FUNCTION__ << endl;
539-#endif
540-
541- /// @todo for now just disable wireless completely.
542- /// this only works properly when there is one wifi adapter on the system
543- try {
544- if (d->m_killSwitch->state() == KillSwitch::State::unblocked) {
545- // block the device. that will disable it also
546- d->m_killSwitch->block();
547- return;
548- }
549- d->m_nm->setWirelessEnabled(false);
550- d->m_dev->setAutoconnect(false);
551- } catch(runtime_error &e) {
552- /// @todo when toggling enable()/disable() rapidly the default timeout of
553- /// 1 second in dbus::core::Property is not long enough..
554- /// just ignore for now and get dbus-cpp to have larger timeout.
555- qWarning() << __PRETTY_FUNCTION__ << ": " << QString::fromStdString(e.what());
556- }
557-
558-#if 0
559- /** @todo remove this after NM 0.9.9 is available. check comment in enable() */
560- m_dev.disconnect();
561-#endif
562-}
563-
564 Link::Type
565 WifiLinkImpl::type() const
566 {
567
568=== modified file 'src/indicator/nmofono/wifi/wifi-link-impl.h'
569--- src/indicator/nmofono/wifi/wifi-link-impl.h 2015-04-14 11:20:17 +0000
570+++ src/indicator/nmofono/wifi/wifi-link-impl.h 2015-08-05 15:22:19 +0000
571@@ -43,9 +43,6 @@
572 ~WifiLinkImpl();
573
574 // public API
575- void enable() override;
576- void disable() override;
577-
578 Type type() const override;
579 Id id() const override;
580 QString name() const override;
581
582=== modified file 'src/indicator/nmofono/wwan/modem.cpp'
583--- src/indicator/nmofono/wwan/modem.cpp 2015-06-18 12:28:05 +0000
584+++ src/indicator/nmofono/wwan/modem.cpp 2015-08-05 15:22:19 +0000
585@@ -671,16 +671,6 @@
586 return WwanType::GSM;
587 }
588
589-void
590-Modem::enable()
591-{
592-}
593-
594-void
595-Modem::disable()
596-{
597-}
598-
599 Link::Type
600 Modem::type() const
601 {
602
603=== modified file 'src/indicator/nmofono/wwan/modem.h'
604--- src/indicator/nmofono/wwan/modem.h 2015-06-18 12:28:05 +0000
605+++ src/indicator/nmofono/wwan/modem.h 2015-08-05 15:22:19 +0000
606@@ -132,10 +132,6 @@
607
608 WwanType wwanType() const override;
609
610- void enable() override;
611-
612- void disable() override;
613-
614 Type type() const override;
615
616 std::uint32_t characteristics() const override;

Subscribers

People subscribed via source and target branches