Merge lp:~unity-api-team/indicator-network/connectivity-service into lp:indicator-network/14.10

Proposed by Antti Kaijanmäki on 2014-08-07
Status: Merged
Approved by: Charles Kerr on 2014-08-07
Approved revision: 390
Merged at revision: 404
Proposed branch: lp:~unity-api-team/indicator-network/connectivity-service
Merge into: lp:indicator-network/14.10
Prerequisite: lp:~unity-api-team/indicator-network/tree-restructure
Diff against target: 852 lines (+610/-47)
15 files modified
src/dbus-cpp/CMakeLists.txt (+1/-0)
src/dbus-cpp/services/connectivity.h (+186/-0)
src/indicator/CMakeLists.txt (+2/-2)
src/indicator/connectivity-service/connectivity-service.cpp (+311/-0)
src/indicator/connectivity-service/connectivity-service.h (+39/-0)
src/indicator/indicator-network-service.cpp (+6/-1)
src/indicator/modem-manager.cpp (+14/-0)
src/indicator/modem-manager.h (+1/-0)
src/indicator/modem.h (+14/-0)
src/indicator/root-state.cpp (+1/-12)
src/indicator/service.h (+8/-2)
src/indicator/sim-unlock-dialog.cpp (+15/-15)
src/indicator/wwan-section.cpp (+7/-12)
src/indicator/wwan-section.h (+2/-0)
src/menumodel-cpp/action-group-merger.h (+3/-3)
To merge this branch: bzr merge lp:~unity-api-team/indicator-network/connectivity-service
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve on 2014-08-19
Charles Kerr (community) 2014-08-07 Approve on 2014-08-07
Review via email: mp+229965@code.launchpad.net

Commit message

Add Connectivity Service.

To post a comment you must log in.
Charles Kerr (charlesk) wrote :

Source LGTM. There are some hacks in there to get DBus introspection working, but since this is an interim solution until dbus-cpp adds service-side introspection support, that's reasonable.

As before, I don't have multisim and am approving only based on code inspection; please don't merge until actual dual sim testing has been done.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/dbus-cpp/CMakeLists.txt'
2--- src/dbus-cpp/CMakeLists.txt 2014-08-07 23:04:23 +0000
3+++ src/dbus-cpp/CMakeLists.txt 2014-08-07 23:04:23 +0000
4@@ -1,5 +1,6 @@
5
6 set(DBUS_CPP_SERVICES
7+ services/connectivity.h
8 services/ofono.h
9 )
10
11
12=== added file 'src/dbus-cpp/services/connectivity.h'
13--- src/dbus-cpp/services/connectivity.h 1970-01-01 00:00:00 +0000
14+++ src/dbus-cpp/services/connectivity.h 2014-08-07 23:04:23 +0000
15@@ -0,0 +1,186 @@
16+/*
17+ * Copyright © 2014 Canonical Ltd.
18+ *
19+ * This program is free software: you can redistribute it and/or modify it
20+ * under the terms of the GNU Lesser General Public License version 3,
21+ * as published by the Free Software Foundation.
22+ *
23+ * This program is distributed in the hope that it will be useful,
24+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26+ * GNU Lesser General Public License for more details.
27+ *
28+ * You should have received a copy of the GNU Lesser General Public License
29+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
30+ *
31+ * Authors: Antti Kaijanmäki <antti.kaijanmaki@canonical.com
32+ */
33+#ifndef DBUS_CPP_SERVICES_UBUNTU_CONNECTIVITY_H
34+#define DBUS_CPP_SERVICES_UBUNTU_CONNECTIVITY_H
35+
36+#include <core/dbus/bus.h>
37+#include <core/dbus/object.h>
38+#include <core/dbus/property.h>
39+#include <core/dbus/service.h>
40+#include <core/dbus/types/object_path.h>
41+#include <core/dbus/types/struct.h>
42+#include <core/dbus/types/stl/map.h>
43+#include <core/dbus/types/stl/string.h>
44+#include <core/dbus/types/stl/tuple.h>
45+#include <core/dbus/types/stl/vector.h>
46+
47+#define UBUNTU_CONNECTIVITY_DBUS_API_VERSION "1"
48+#define UBUNTU_CONNECTIVITY_NAME_BASE "com.ubuntu.connectivity" UBUNTU_CONNECTIVITY_DBUS_API_VERSION
49+#define UBUNTU_CONNECTIVITY_PATH_BASE "/com/ubuntu/connectivity" UBUNTU_CONNECTIVITY_DBUS_API_VERSION
50+
51+#define UBUNTU_CONNECTIVITY_SERVICE_NAME UBUNTU_CONNECTIVITY_NAME_BASE
52+#define UBUNTU_CONNECTIVITY_SERVICE_PATH UBUNTU_CONNECTIVITY_PATH_BASE
53+
54+namespace com
55+{
56+namespace ubuntu
57+{
58+namespace connectivity
59+{
60+
61+struct Interface
62+{
63+ struct NetworkingStatus
64+ {
65+ static const std::string& name()
66+ {
67+ static const std::string s{UBUNTU_CONNECTIVITY_NAME_BASE ".NetworkingStatus"};
68+ return s;
69+ }
70+ static const std::string& path()
71+ {
72+ static const std::string s{UBUNTU_CONNECTIVITY_PATH_BASE "/NetworkingStatus"};
73+ return s;
74+ }
75+
76+ struct Property
77+ {
78+ struct Limitations {
79+ static const std::string &name()
80+ {
81+ static const std::string s{"Limitations"};
82+ return s;
83+ }
84+
85+ typedef NetworkingStatus Interface;
86+ typedef std::vector<std::string> ValueType;
87+ static const bool readable = true;
88+ static const bool writable = false;
89+ };
90+
91+ struct Status {
92+ static const std::string &name()
93+ {
94+ static const std::string s{"Status"};
95+ return s;
96+ }
97+
98+ typedef NetworkingStatus Interface;
99+ typedef std::string ValueType;
100+ static const bool readable = true;
101+ static const bool writable = false;
102+ };
103+ };
104+
105+ NetworkingStatus(std::shared_ptr<core::dbus::Service> &service,
106+ std::shared_ptr<core::dbus::Object> &object)
107+ : service(service),
108+ object(object)
109+ {
110+
111+ }
112+
113+ std::shared_ptr<core::dbus::Service> service;
114+ std::shared_ptr<core::dbus::Object> object;
115+ };
116+
117+ struct Private
118+ {
119+ static const std::string& name()
120+ {
121+ static const std::string s{UBUNTU_CONNECTIVITY_NAME_BASE ".Private"};
122+ return s;
123+ }
124+ static const std::string& path()
125+ {
126+ static const std::string s{UBUNTU_CONNECTIVITY_PATH_BASE "/Private"};
127+ return s;
128+ }
129+
130+ struct Method
131+ {
132+ struct UnlockAllModems {
133+ static const std::string& name()
134+ {
135+ static const std::string s{"UnlockAllModems"};
136+ return s;
137+ }
138+
139+ typedef Private Interface;
140+ typedef void ValueType;
141+
142+ static std::chrono::milliseconds default_timeout()
143+ {
144+ return std::chrono::seconds{1};
145+ }
146+ };
147+ };
148+
149+ Private(std::shared_ptr<core::dbus::Service> &service,
150+ std::shared_ptr<core::dbus::Object> &object)
151+ : service(service),
152+ object(object)
153+ {}
154+
155+ std::shared_ptr<core::dbus::Service> service;
156+ std::shared_ptr<core::dbus::Object> object;
157+ };
158+
159+
160+}; // Interface
161+
162+struct Service
163+{
164+ std::shared_ptr<Interface::NetworkingStatus> networkingStatus;
165+
166+ static const std::string& name()
167+ {
168+ static const std::string s{UBUNTU_CONNECTIVITY_SERVICE_NAME};
169+ return s;
170+ }
171+
172+ Service(const core::dbus::Bus::Ptr& bus)
173+ {
174+ auto service = core::dbus::Service::use_service<Service>(bus);
175+ auto object = service->object_for_path(core::dbus::types::ObjectPath(Interface::NetworkingStatus::path()));
176+ try {
177+ networkingStatus = std::make_shared<Interface::NetworkingStatus>(service, object);
178+ } catch (const std::exception &e) {
179+ std::cerr << "Failed to access NetworkingStatus interface: " << e.what() << std::endl;
180+ }
181+ }
182+
183+ struct Mock
184+ {
185+ std::shared_ptr<Interface::NetworkingStatus> networkingStatus;
186+
187+ Mock(const core::dbus::Bus::Ptr& bus)
188+ {
189+ auto service = core::dbus::Service::add_service<Service>(bus);
190+ auto object = service->add_object_for_path(core::dbus::types::ObjectPath(Interface::NetworkingStatus::path()));
191+ networkingStatus = std::make_shared<Interface::NetworkingStatus>(service, object);
192+ }
193+ };
194+};
195+
196+}
197+}
198+}
199+
200+#endif // DBUS_CPP_SERVICES_UBUNTU_CONNECTIVITY_H
201+
202
203=== modified file 'src/indicator/CMakeLists.txt'
204--- src/indicator/CMakeLists.txt 2014-08-07 23:04:23 +0000
205+++ src/indicator/CMakeLists.txt 2014-08-07 23:04:23 +0000
206@@ -17,6 +17,8 @@
207 wwan-link-item.cpp
208 wwan-section.cpp
209
210+ connectivity-service/connectivity-service.cpp
211+
212 menuitems/access-point-item.h
213 menuitems/item.h
214 menuitems/modem-info-item.cpp
215@@ -25,8 +27,6 @@
216 menuitems/text-item.h
217 )
218
219-#include_directories(include)
220-
221 # get std::thread working...
222 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52681
223 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
224
225=== added directory 'src/indicator/connectivity-service'
226=== added file 'src/indicator/connectivity-service/connectivity-service.cpp'
227--- src/indicator/connectivity-service/connectivity-service.cpp 1970-01-01 00:00:00 +0000
228+++ src/indicator/connectivity-service/connectivity-service.cpp 2014-08-07 23:04:23 +0000
229@@ -0,0 +1,311 @@
230+/*
231+ * Copyright (C) 2014 Canonical, Ltd.
232+ *
233+ * This program is free software: you can redistribute it and/or modify it
234+ * under the terms of the GNU General Public License version 3, as published
235+ * by the Free Software Foundation.
236+ *
237+ * This program is distributed in the hope that it will be useful, but
238+ * WITHOUT ANY WARRANTY; without even the implied warranties of
239+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
240+ * PURPOSE. See the GNU General Public License for more details.
241+ *
242+ * You should have received a copy of the GNU General Public License along
243+ * with this program. If not, see <http://www.gnu.org/licenses/>.
244+ *
245+ * Authors:
246+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
247+ */
248+
249+#include "connectivity-service.h"
250+#include <dbus-cpp/services/connectivity.h>
251+
252+#include <core/dbus/asio/executor.h>
253+#include <core/dbus/helper/type_mapper.h>
254+
255+#include <sstream>
256+
257+namespace networking = connectivity::networking;
258+
259+template<typename T>
260+std::string generatePropertyIntrospectionXml()
261+{
262+ std::ostringstream output;
263+
264+ output << "<property ";
265+ output << "name=\"" << T::name() << "\" ";
266+ output << "type=\"" << core::dbus::helper::TypeMapper<typename T::ValueType>::signature() << "\" ";
267+
268+ output << "access=\"";
269+ if (T::readable && T::writable)
270+ output << "readwrite";
271+ else if (T::readable && !T::writable)
272+ output << "read";
273+ else if (!T::readable && T::writable)
274+ output << "write";
275+ else
276+ throw(std::logic_error("Property defined as neither readable nor writable."));
277+ output << "\"";
278+
279+ output << "/>";
280+ return output.str();
281+}
282+
283+namespace {
284+struct Interface {
285+struct Introspectable
286+{
287+ inline static const std::string& name()
288+ {
289+ static const std::string s{"org.freedesktop.DBus.Introspectable"};
290+ return s;
291+ }
292+
293+ struct Method
294+ {
295+ struct Introspect
296+ {
297+ typedef Introspectable Interface;
298+ inline static std::string name()
299+ {
300+ return "Introspect";
301+ }
302+ static const bool call_synchronously = true;
303+ inline static const std::chrono::milliseconds default_timeout()
304+ {
305+ return std::chrono::seconds{1};
306+ }
307+ };
308+ };
309+};
310+};
311+}
312+
313+class ConnectivityService::Private
314+{
315+public:
316+ std::thread m_connectivityServiceWorker;
317+
318+ core::dbus::Bus::Ptr m_bus;
319+ core::dbus::Service::Ptr m_service;
320+
321+ core::dbus::Object::Ptr m_networkingStatusObject;
322+ std::shared_ptr<com::ubuntu::connectivity::Interface::NetworkingStatus> m_networkingStatus;
323+ std::shared_ptr<core::dbus::Property<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations>> m_limitations;
324+ std::shared_ptr<core::dbus::Property<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status>> m_status;
325+ core::dbus::Signal<core::dbus::interfaces::Properties::Signals::PropertiesChanged,
326+ core::dbus::interfaces::Properties::Signals::PropertiesChanged::ArgumentType>::Ptr m_propertiesChanged;
327+
328+ core::dbus::Object::Ptr m_privateObject;
329+ std::shared_ptr<com::ubuntu::connectivity::Interface::Private> m_private;
330+
331+ core::Signal<> m_unlockAllModems;
332+
333+ std::shared_ptr<networking::Manager> m_manager;
334+
335+ Private() = delete;
336+ Private(std::shared_ptr<networking::Manager> manager);
337+ ~Private();
338+
339+ void updateNetworkingStatus();
340+
341+ std::string introspectXml();
342+};
343+
344+ConnectivityService::Private::Private(std::shared_ptr<networking::Manager> manager)
345+ : m_manager{manager}
346+{
347+ m_manager->characteristics().changed().connect(std::bind(&Private::updateNetworkingStatus, this));
348+ m_manager->status().changed().connect(std::bind(&Private::updateNetworkingStatus, this));
349+
350+ m_bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
351+
352+ auto executor = core::dbus::asio::make_executor(m_bus);
353+ m_bus->install_executor(executor);
354+ m_connectivityServiceWorker = std::move(std::thread([this](){ m_bus->run(); }));
355+
356+ m_service = core::dbus::Service::add_service<com::ubuntu::connectivity::Service>(m_bus);
357+
358+ m_networkingStatusObject = m_service->add_object_for_path(core::dbus::types::ObjectPath(com::ubuntu::connectivity::Interface::NetworkingStatus::path()));
359+ m_networkingStatus = std::make_shared<com::ubuntu::connectivity::Interface::NetworkingStatus>(m_service, m_networkingStatusObject);
360+ m_propertiesChanged = m_networkingStatusObject->get_signal<core::dbus::interfaces::Properties::Signals::PropertiesChanged>();
361+
362+
363+ m_networkingStatusObject->install_method_handler<Interface::Introspectable::Method::Introspect>([this](const core::dbus::Message::Ptr& msg)
364+ {
365+ auto reply = core::dbus::Message::make_method_return(msg);
366+ reply->writer() << introspectXml();
367+ m_bus->send(reply);
368+ });
369+
370+ m_limitations = m_networkingStatusObject->get_property<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations>();
371+ m_status = m_networkingStatusObject->get_property<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status>();
372+
373+ updateNetworkingStatus();
374+
375+ m_networkingStatusObject->install_method_handler<core::dbus::interfaces::Properties::GetAll>([this](const core::dbus::Message::Ptr& msg)
376+ {
377+
378+ core::dbus::Message::Reader reader;
379+ try {
380+ reader = msg->reader();
381+ } catch(...) {
382+ m_bus->send(core::dbus::Message::make_error(msg, "need.to.add.full.properties.support.to.dbus.cpp", "invalid argument."));
383+ return;
384+ }
385+ if (reader.type() != core::dbus::ArgumentType::string) {
386+ m_bus->send(core::dbus::Message::make_error(msg, "need.to.add.full.properties.support.to.dbus.cpp", "invalid argument."));
387+ return;
388+ }
389+ std::string interface = reader.pop_string();
390+
391+ if (interface != com::ubuntu::connectivity::Interface::NetworkingStatus::name()) {
392+ m_bus->send(core::dbus::Message::make_error(msg, "need.to.add.full.properties.support.to.dbus.cpp", "no such interface."));
393+ return;
394+ }
395+
396+ auto reply = core::dbus::Message::make_method_return(msg);
397+ std::map<std::string, core::dbus::types::Variant> props;
398+ props[com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations::name()]
399+ = core::dbus::types::TypedVariant<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations::ValueType>(m_limitations->get());
400+ props[com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status::name()]
401+ = core::dbus::types::TypedVariant<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status::ValueType>(m_status->get());
402+ reply->writer() << props;
403+ m_bus->send(reply);
404+ });
405+
406+ m_privateObject = m_service->add_object_for_path(core::dbus::types::ObjectPath(com::ubuntu::connectivity::Interface::Private::path()));
407+ m_privateObject->install_method_handler<com::ubuntu::connectivity::Interface::Private::Method::UnlockAllModems>([this](const core::dbus::Message::Ptr& msg)
408+ {
409+ auto reply = core::dbus::Message::make_method_return(msg);
410+ m_bus->send(reply);
411+ m_unlockAllModems();
412+ });
413+}
414+
415+ConnectivityService::Private::~Private()
416+{
417+ m_bus->stop();
418+ try {
419+ if (m_connectivityServiceWorker.joinable())
420+ m_connectivityServiceWorker.join();
421+ } catch(const std::system_error &e) {
422+ // This is the only exception type that may be thrown.
423+ // http://en.cppreference.com/w/cpp/thread/thread/join
424+ std::cerr << "Error when destroying worker thread, error code " << e.code()
425+ << ", error message: " << e.what() << std::endl;
426+ }
427+}
428+
429+void
430+ConnectivityService::Private::updateNetworkingStatus()
431+{
432+ std::vector<std::string> old_limitations = m_limitations->get();
433+ std::string old_status = m_status->get();
434+
435+ switch(m_manager->status().get()) {
436+ case networking::Manager::NetworkingStatus::offline:
437+ m_status->set("offline");
438+ break;
439+ case networking::Manager::NetworkingStatus::connecting:
440+ m_status->set("connecting");
441+ break;
442+ case networking::Manager::NetworkingStatus::online:
443+ m_status->set("online");
444+ }
445+ if (old_status.empty()) {
446+ // initially not set
447+ old_status = m_status->get();
448+ }
449+
450+
451+ std::vector<std::string> limitations;
452+ auto characteristics = m_manager->characteristics().get();
453+ if ((characteristics & networking::Link::Characteristics::is_bandwidth_limited) != 0) {
454+ limitations.push_back("bandwith");
455+ }
456+ m_limitations->set(limitations);
457+
458+ std::map<std::string, core::dbus::types::Variant> changed;
459+ if (old_limitations != m_limitations->get()) {
460+ changed[com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations::name()]
461+ = core::dbus::types::TypedVariant<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations::ValueType>(m_limitations->get());
462+ }
463+ if (old_status != m_status->get()) {
464+ changed[com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status::name()]
465+ = core::dbus::types::TypedVariant<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status::ValueType>(m_status->get());
466+ }
467+
468+ if (changed.size() != 0) {
469+ core::dbus::interfaces::Properties::Signals::PropertiesChanged::ArgumentType args
470+ (com::ubuntu::connectivity::Interface::NetworkingStatus::name(),
471+ changed,
472+ {}
473+ );
474+ m_propertiesChanged->emit(args);
475+ }
476+}
477+
478+std::string
479+ConnectivityService::Private::introspectXml()
480+{
481+ std::ostringstream output;
482+
483+ static const std::string header(
484+ "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\n"
485+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
486+ "<node>\n"
487+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
488+ " <method name=\"Introspect\">\n"
489+ " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
490+ " </method>\n"
491+ " </interface>\n"
492+ " <interface name=\"org.freedesktop.DBus.Properties\">\n"
493+ " <method name=\"Get\">\n"
494+ " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"
495+ " <arg name=\"propname\" direction=\"in\" type=\"s\"/>\n"
496+ " <arg name=\"value\" direction=\"out\" type=\"v\"/>\n"
497+ " </method>\n"
498+ " <method name=\"Set\">\n"
499+ " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"
500+ " <arg name=\"propname\" direction=\"in\" type=\"s\"/>\n"
501+ " <arg name=\"value\" direction=\"in\" type=\"v\"/>\n"
502+ " </method>\n"
503+ " <method name=\"GetAll\">\n"
504+ " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n"
505+ " <arg name=\"props\" direction=\"out\" type=\"a{sv}\"/>\n"
506+ " </method>\n"
507+ " <signal name=\"PropertiesChanged\"\n>"
508+ " <arg type=\"s\" name=\"interface_name\"/>\n"
509+ " <arg type=\"a{sv}\" name=\"changed_properties\"/>\n"
510+ " <arg type=\"as\" name=\"invalidated_properties\"/>\n"
511+ " </signal>\n"
512+ " </interface>\n");
513+
514+ static const std::string footer("</node>\n");
515+
516+ output << header;
517+
518+ output << "<interface name=\"" << com::ubuntu::connectivity::Interface::NetworkingStatus::name() << "\">\n";
519+ output << generatePropertyIntrospectionXml<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Limitations>() << std::endl;
520+ output << generatePropertyIntrospectionXml<com::ubuntu::connectivity::Interface::NetworkingStatus::Property::Status>() << std::endl;
521+ output << "</interface>\n";
522+
523+ output << footer;
524+
525+ return output.str();
526+}
527+
528+ConnectivityService::ConnectivityService(std::shared_ptr<networking::Manager> manager)
529+ : d{new Private(manager)}
530+{}
531+
532+ConnectivityService::~ConnectivityService()
533+{}
534+
535+core::Signal<> &
536+ConnectivityService::unlockAllModems()
537+{
538+ return d->m_unlockAllModems;
539+}
540+
541
542=== added file 'src/indicator/connectivity-service/connectivity-service.h'
543--- src/indicator/connectivity-service/connectivity-service.h 1970-01-01 00:00:00 +0000
544+++ src/indicator/connectivity-service/connectivity-service.h 2014-08-07 23:04:23 +0000
545@@ -0,0 +1,39 @@
546+/*
547+ * Copyright (C) 2014 Canonical, Ltd.
548+ *
549+ * This program is free software: you can redistribute it and/or modify it
550+ * under the terms of the GNU General Public License version 3, as published
551+ * by the Free Software Foundation.
552+ *
553+ * This program is distributed in the hope that it will be useful, but
554+ * WITHOUT ANY WARRANTY; without even the implied warranties of
555+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
556+ * PURPOSE. See the GNU General Public License for more details.
557+ *
558+ * You should have received a copy of the GNU General Public License along
559+ * with this program. If not, see <http://www.gnu.org/licenses/>.
560+ *
561+ * Authors:
562+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
563+ */
564+
565+#ifndef CONNECTIVITY_SERVICE_H
566+#define CONNECTIVITY_SERVICE_H
567+
568+#include <connectivity/networking/manager.h>
569+#include<core/signal.h>
570+
571+class ConnectivityService
572+{
573+public:
574+ ConnectivityService(std::shared_ptr<connectivity::networking::Manager> manager);
575+ virtual ~ConnectivityService();
576+
577+ core::Signal<> &unlockAllModems();
578+
579+private:
580+ class Private;
581+ std::unique_ptr<Private> d;
582+};
583+
584+#endif
585
586=== modified file 'src/indicator/indicator-network-service.cpp'
587--- src/indicator/indicator-network-service.cpp 2014-03-25 23:22:16 +0000
588+++ src/indicator/indicator-network-service.cpp 2014-08-07 23:04:23 +0000
589@@ -18,6 +18,7 @@
590 */
591
592 #include "service.h"
593+#include "connectivity-service/connectivity-service.h"
594
595 #include <iostream>
596 #include <memory>
597@@ -81,7 +82,11 @@
598
599 notify_init(GETTEXT_PACKAGE);
600
601- std::unique_ptr<Service> menu {new Service};
602+ std::shared_ptr<networking::Manager> manager = networking::Manager::createInstance();
603+
604+ std::shared_ptr<Service> menu {new Service(manager)};
605+ std::unique_ptr<ConnectivityService> connectivityService {new ConnectivityService(manager)};
606+ connectivityService->unlockAllModems().connect([menu](){ menu->unlockAllModems(); });
607
608 if (getenv("VALGRIND") != 0) {
609 g_timeout_add(1000, (GSourceFunc)stop_main_loop, NULL);
610
611=== modified file 'src/indicator/modem-manager.cpp'
612--- src/indicator/modem-manager.cpp 2014-06-06 11:05:21 +0000
613+++ src/indicator/modem-manager.cpp 2014-08-07 23:04:23 +0000
614@@ -193,6 +193,20 @@
615 d->m_pendingUnlocks.push_back(modem);
616 }
617
618+void
619+ModemManager::unlockAllModems()
620+{
621+ std::cout << __PRETTY_FUNCTION__ << std::endl;
622+ std::multimap<int, Modem::Ptr, Modem::Compare> sorted;
623+ for (auto m : d->m_modems.get()) {
624+ sorted.insert(std::make_pair(m->index(), m));
625+ }
626+ for (auto pair : sorted) {
627+ std::cout << "Unlocking " << pair.second->simIdentifier().get() << std::endl;
628+ unlockModem(pair.second);
629+ }
630+}
631+
632
633 const core::Property<std::set<Modem::Ptr>> &
634 ModemManager::modems()
635
636=== modified file 'src/indicator/modem-manager.h'
637--- src/indicator/modem-manager.h 2014-04-23 13:18:25 +0000
638+++ src/indicator/modem-manager.h 2014-08-07 23:04:23 +0000
639@@ -38,6 +38,7 @@
640 ~ModemManager();
641
642 void unlockModem(Modem::Ptr modem);
643+ void unlockAllModems();
644
645 const core::Property<std::set<Modem::Ptr>> &modems();
646 };
647
648=== modified file 'src/indicator/modem.h'
649--- src/indicator/modem.h 2014-08-07 00:19:35 +0000
650+++ src/indicator/modem.h 2014-08-07 23:04:23 +0000
651@@ -52,6 +52,20 @@
652 typedef std::shared_ptr<Modem> Ptr;
653 typedef std::weak_ptr<Modem> WeakPtr;
654
655+ struct Compare
656+ {
657+ bool operator()(int lhs, int rhs)
658+ {
659+ if (lhs == -1 && rhs == -1)
660+ return false;
661+ if (lhs == -1)
662+ return false;
663+ if (rhs == -1)
664+ return true;
665+ return lhs < rhs;
666+ }
667+ };
668+
669 Modem() = delete;
670 Modem(org::ofono::Interface::Modem::Ptr ofonoModem);
671 virtual ~Modem();
672
673=== modified file 'src/indicator/root-state.cpp'
674--- src/indicator/root-state.cpp 2014-08-07 01:31:06 +0000
675+++ src/indicator/root-state.cpp 2014-08-07 23:04:23 +0000
676@@ -261,18 +261,7 @@
677 break;
678 }
679
680- auto compare = [](int lhs, int rhs ){
681- // make sure index() == -1 goes as leftmost cellular icon
682- if (lhs == -1 && rhs == -1)
683- return false;
684- if (lhs == -1)
685- return false;
686- if (rhs == -1)
687- return true;
688- return lhs < rhs;
689- };
690- std::multimap<int, std::string, decltype(compare)> sorted(compare);
691-
692+ std::multimap<int, std::string, Modem::Compare> sorted;
693 for (auto pair : m_cellularIcons) {
694 sorted.insert(std::make_pair(pair.first->index(), pair.second));
695 }
696
697=== modified file 'src/indicator/service.h'
698--- src/indicator/service.h 2014-07-01 13:58:06 +0000
699+++ src/indicator/service.h 2014-08-07 23:04:23 +0000
700@@ -85,11 +85,12 @@
701 std::unique_ptr<BusName> m_busName;
702
703 public:
704- Service()
705+ Service() = delete;
706+ Service(std::shared_ptr<connectivity::networking::Manager> manager)
707+ : m_manager{manager}
708 {
709 m_sessionBus.reset(new SessionBus());
710
711- m_manager = networking::Manager::createInstance();
712 m_modemManager = std::make_shared<ModemManager>();
713
714 m_rootState = std::make_shared<RootState>(m_manager, m_modemManager);
715@@ -154,6 +155,11 @@
716 [](std::string) { std::cout << "lost" << std::endl; },
717 m_sessionBus));
718 }
719+
720+ void unlockAllModems()
721+ {
722+ m_wwanSection->unlockAllModems();
723+ }
724 };
725
726 #endif
727
728=== modified file 'src/indicator/sim-unlock-dialog.cpp'
729--- src/indicator/sim-unlock-dialog.cpp 2014-05-22 08:58:56 +0000
730+++ src/indicator/sim-unlock-dialog.cpp 2014-08-07 23:04:23 +0000
731@@ -334,21 +334,6 @@
732 c.disconnect();
733 d->m_connections.clear();
734
735- auto c = modem->requiredPin().changed().connect(std::bind(&Private::update, d.get()));
736- d->m_connections.push_back(c);
737-
738- c = modem->retries().changed().connect(std::bind(&Private::update, d.get()));
739- d->m_connections.push_back(c);
740-
741- c = d->m_sd->cancelled().connect(std::bind(&Private::cancelled, d.get()));
742- d->m_connections.push_back(c);
743-
744- c = d->m_sd->pinEntered().connect(std::bind(&Private::pinEntered, d.get(), std::placeholders::_1));
745- d->m_connections.push_back(c);
746-
747- c = d->m_sd->closed().connect(std::bind(&Private::closed, d.get()));
748- d->m_connections.push_back(c);
749-
750 auto retries = modem->retries().get();
751 auto type = modem->requiredPin().get();
752 switch(type){
753@@ -363,6 +348,21 @@
754 break;
755 }
756
757+ auto c = modem->requiredPin().changed().connect(std::bind(&Private::update, d.get()));
758+ d->m_connections.push_back(c);
759+
760+ c = modem->retries().changed().connect(std::bind(&Private::update, d.get()));
761+ d->m_connections.push_back(c);
762+
763+ c = d->m_sd->cancelled().connect(std::bind(&Private::cancelled, d.get()));
764+ d->m_connections.push_back(c);
765+
766+ c = d->m_sd->pinEntered().connect(std::bind(&Private::pinEntered, d.get(), std::placeholders::_1));
767+ d->m_connections.push_back(c);
768+
769+ c = d->m_sd->closed().connect(std::bind(&Private::closed, d.get()));
770+ d->m_connections.push_back(c);
771+
772 int pinRetries = -1;
773 int pukRetries = -1;
774
775
776=== modified file 'src/indicator/wwan-section.cpp'
777--- src/indicator/wwan-section.cpp 2014-08-07 00:51:19 +0000
778+++ src/indicator/wwan-section.cpp 2014-08-07 23:04:23 +0000
779@@ -124,18 +124,7 @@
780 /// @todo add MenuMerger::insert() and ::find()
781 m_linkMenuMerger->clear();
782
783- auto compare = [](int lhs, int rhs ){
784- // make sure index() == -1 goes to the bottom of the menu
785- if (lhs == -1 && rhs == -1)
786- return false;
787- if (lhs == -1)
788- return false;
789- if (rhs == -1)
790- return true;
791- return lhs < rhs;
792- };
793- std::multimap<int, WwanLinkItem::Ptr, decltype(compare)> sorted(compare);
794-
795+ std::multimap<int, WwanLinkItem::Ptr, Modem::Compare> sorted;
796 for (auto pair : m_items) {
797 sorted.insert(std::make_pair(pair.first->index(), pair.second));
798 }
799@@ -180,3 +169,9 @@
800 {
801 return d->m_topMenu;
802 }
803+
804+void
805+WwanSection::unlockAllModems()
806+{
807+ d->m_modemManager->unlockAllModems();
808+}
809
810=== modified file 'src/indicator/wwan-section.h'
811--- src/indicator/wwan-section.h 2014-04-02 22:10:27 +0000
812+++ src/indicator/wwan-section.h 2014-08-07 23:04:23 +0000
813@@ -36,6 +36,8 @@
814
815 virtual ActionGroup::Ptr actionGroup();
816 virtual MenuModel::Ptr menuModel();
817+
818+ void unlockAllModems();
819 };
820
821 #endif
822
823=== modified file 'src/menumodel-cpp/action-group-merger.h'
824--- src/menumodel-cpp/action-group-merger.h 2014-04-01 10:03:34 +0000
825+++ src/menumodel-cpp/action-group-merger.h 2014-08-07 23:04:23 +0000
826@@ -61,7 +61,7 @@
827 // then they will override each other in GActionGroup so let's catch that
828 // early on.
829 if (name_iter->second != action) {
830- std::cerr << "Conflicting action names." << std::endl;
831+ std::cerr << __PRETTY_FUNCTION__ << ": Conflicting action names. \"" << action->name() << "\"" << std::endl;
832 /// @todo thow something.
833 return;
834 }
835@@ -107,7 +107,7 @@
836 auto iter = m_groups.find(group);
837 if (iter != m_groups.end()) {
838 /// @todo throw something.
839- std::cerr << "Trying to add action group which was already added before." << std::endl;
840+ std::cerr << __PRETTY_FUNCTION__ << ": Trying to add action group which was already added before." << std::endl;
841 return;
842 }
843
844@@ -128,7 +128,7 @@
845 auto iter = m_groups.find(group);
846 if (iter == m_groups.end()) {
847 /// @todo throw something.
848- std::cerr << "Trying to remove action group which was not added before." << std::endl;
849+ std::cerr << __PRETTY_FUNCTION__ << ": Trying to remove action group which was not added before." << std::endl;
850 return;
851 }
852 m_groups.erase(group);

Subscribers

People subscribed via source and target branches