Merge lp:~unity-api-team/indicator-network/connectivity-api-mobile-data-management-tests into lp:indicator-network

Proposed by Pete Woods
Status: Merged
Approved by: Pete Woods
Approved revision: 637
Merged at revision: 602
Proposed branch: lp:~unity-api-team/indicator-network/connectivity-api-mobile-data-management-tests
Merge into: lp:indicator-network
Prerequisite: lp:~unity-api-team/indicator-network/mobile-switch
Diff against target: 3470 lines (+1677/-332)
33 files modified
data/com.ubuntu.connectivity1.Sim.xml (+1/-0)
debian/control (+1/-1)
src/connectivity-api/connectivity-qt/connectivityqt/connectivity.cpp (+3/-0)
src/connectivity-api/connectivity-qt/connectivityqt/modem.cpp (+4/-4)
src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.cpp (+4/-1)
src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.h (+2/-0)
src/connectivity-api/connectivity-qt/connectivityqt/sim.cpp (+11/-6)
src/connectivity-api/connectivity-qt/connectivityqt/sim.h (+11/-8)
src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.cpp (+28/-4)
src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.h (+5/-8)
src/indicator/connectivity-service/connectivity-service.cpp (+51/-25)
src/indicator/connectivity-service/dbus-modem.cpp (+1/-1)
src/indicator/connectivity-service/dbus-sim.cpp (+30/-1)
src/indicator/connectivity-service/dbus-sim.h (+7/-0)
src/indicator/factory.cpp (+2/-2)
src/indicator/nmofono/connectivity-service-settings.cpp (+31/-21)
src/indicator/nmofono/connectivity-service-settings.h (+2/-2)
src/indicator/nmofono/manager-impl.cpp (+106/-56)
src/indicator/nmofono/wwan/modem.cpp (+27/-0)
src/indicator/nmofono/wwan/qofono-sim-wrapper.cpp (+21/-112)
src/indicator/nmofono/wwan/qofono-sim-wrapper.h (+1/-4)
src/indicator/nmofono/wwan/sim-manager.cpp (+36/-36)
src/indicator/nmofono/wwan/sim-manager.h (+3/-1)
src/indicator/nmofono/wwan/sim.cpp (+104/-14)
src/indicator/nmofono/wwan/sim.h (+22/-6)
src/qdbus-stubs/dbus-types.h (+6/-4)
tests/integration/CMakeLists.txt (+2/-0)
tests/integration/indicator-network-test-base.cpp (+40/-9)
tests/integration/indicator-network-test-base.h (+32/-3)
tests/integration/test-connectivity-api-modem.cpp (+322/-0)
tests/integration/test-connectivity-api-sim.cpp (+375/-0)
tests/integration/test-connectivity-api.cpp (+124/-0)
tests/integration/test-indicator.cpp (+262/-3)
To merge this branch: bzr merge lp:~unity-api-team/indicator-network/connectivity-api-mobile-data-management-tests
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Pending
Indicator Applet Developers Pending
Review via email: mp+295939@code.launchpad.net

This proposal supersedes a proposal from 2016-05-27.

Commit message

New Connectivity Service Private API for managing mobile data and SIM cards. Tests.

Description of the change

New Connectivity Service Private API for managing mobile data and SIM cards. Tests.

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
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
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
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
604. By Pete Woods

Use a sequence for generating DBus paths

605. By Pete Woods

Create our own modem

606. By Pete Woods

Start implementing the modem model tests

607. By Pete Woods

Init the Sims model before we use it

608. By Pete Woods

Remove phone numbers property

609. By Pete Woods

Get more ModemsListModel tests working

610. By Antti Kaijanmäki

add a test for mobile data switch.

611. By Antti Kaijanmäki

more indicator tests.

612. By Antti Kaijanmäki

merge.

613. By Antti Kaijanmäki

no macros

614. By Antti Kaijanmäki

fix cellular2

615. By Antti Kaijanmäki

merge

616. By Pete Woods

Start making a test for mobile data selector

617. By Antti Kaijanmäki

first try of initial mobile data heuristics.

618. By Antti Kaijanmäki

debug tests

619. By Antti Kaijanmäki

make tests pass.

620. By Antti Kaijanmäki

fix build on vivid.

621. By Antti Kaijanmäki

fix build on vivid 2.

622. By Antti Kaijanmäki

Switch from IMSI to ICCID

623. By Antti Kaijanmäki

Fix rest of the tests.

624. By Antti Kaijanmäki

remove sim_general.xml

625. By Antti Kaijanmäki

foofix

626. By Antti Kaijanmäki

DISABLE TESTS

627. By Antti Kaijanmäki

add IMSI to SIM interface.

628. By Antti Kaijanmäki

indicator: check that simForMobileData is also present before enabling the switch.

629. By Antti Kaijanmäki

fix small bugs.

630. By Antti Kaijanmäki

whoopsie

631. By Antti Kaijanmäki

remove debugging stuff

632. By Antti Kaijanmäki

augment tests and visual cleanup.

633. By Antti Kaijanmäki

Fix a bug where mobile data is not restored properly on startup.

634. By Antti Kaijanmäki

RE-ENABLE TESTS

635. By Antti Kaijanmäki

make "hotplugged" SIMs work.

636. By Antti Kaijanmäki

fix initial imsi

637. By Antti Kaijanmäki

do not wait on MCC and MNC

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/com.ubuntu.connectivity1.Sim.xml'
2--- data/com.ubuntu.connectivity1.Sim.xml 2016-06-22 09:42:47 +0000
3+++ data/com.ubuntu.connectivity1.Sim.xml 2016-06-22 09:42:47 +0000
4@@ -2,6 +2,7 @@
5
6 <node>
7 <interface name="com.ubuntu.connectivity1.Sim">
8+ <property name="Iccid" type="s" access="read" />
9 <property name="Imsi" type="s" access="read" />
10 <property name="PrimaryPhoneNumber" type="s" access="read" />
11 <property name="Locked" type="b" access="read" />
12
13=== modified file 'debian/control'
14--- debian/control 2016-02-15 09:31:38 +0000
15+++ debian/control 2016-06-22 09:42:47 +0000
16@@ -12,7 +12,7 @@
17 graphviz,
18 intltool,
19 libglib2.0-dev,
20- libgmenuharness-dev,
21+ libgmenuharness-dev (>= 0.1.1),
22 libqofono-dev,
23 libqofono-qt5-0,
24 libqtdbusmock1-dev (>= 0.4),
25
26=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/connectivity.cpp'
27--- src/connectivity-api/connectivity-qt/connectivityqt/connectivity.cpp 2016-06-22 09:42:47 +0000
28+++ src/connectivity-api/connectivity-qt/connectivityqt/connectivity.cpp 2016-06-22 09:42:47 +0000
29@@ -180,6 +180,7 @@
30 else if (name == "SimForMobileData")
31 {
32 auto path = value.value<QDBusObjectPath>();
33+ p.sims();
34 auto sim = m_simsModel->getSimByPath(path);
35 p.setSimForMobileData(sim.get());
36 }
37@@ -188,6 +189,7 @@
38 void simsUpdated()
39 {
40 auto path = m_writePropertyCache->get("SimForMobileData").value<QDBusObjectPath>();
41+ p.sims();
42 auto sim = m_simsModel->getSimByPath(path);
43 p.setSimForMobileData(sim.get());
44 }
45@@ -424,6 +426,7 @@
46
47 Sim *Connectivity::simForMobileData() const
48 {
49+ sims();
50 return d->m_simForMobileData.get();
51 }
52
53
54=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/modem.cpp'
55--- src/connectivity-api/connectivity-qt/connectivityqt/modem.cpp 2016-06-22 09:42:47 +0000
56+++ src/connectivity-api/connectivity-qt/connectivityqt/modem.cpp 2016-06-22 09:42:47 +0000
57@@ -43,14 +43,14 @@
58 {
59 if (name == "Sim")
60 {
61- auto sim = m_sims->getSimByPath(value.value<QDBusObjectPath>());
62- setSim(sim);
63+ simsUpdated();
64 }
65 }
66
67 void simsUpdated()
68 {
69- auto sim = m_sims->getSimByPath(m_propertyCache->get("Sim").value<QDBusObjectPath>());
70+ auto path = m_propertyCache->get("Sim").value<QDBusObjectPath>();
71+ auto sim = m_sims->getSimByPath(path);
72 setSim(sim);
73 }
74
75@@ -96,7 +96,7 @@
76 &internal::DBusPropertyCache::propertyChanged, d.get(),
77 &Priv::propertyChanged);
78
79- d->m_sim = d->m_sims->getSimByPath(d->m_propertyCache->get("Sim").value<QDBusObjectPath>());
80+ d->simsUpdated();
81
82 connect(d->m_sims.get(), &SimsListModel::simsUpdated, d.get(), &Priv::simsUpdated);
83 }
84
85=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.cpp'
86--- src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.cpp 2016-06-22 09:42:47 +0000
87+++ src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.cpp 2016-06-22 09:42:47 +0000
88@@ -77,7 +77,7 @@
89 p.beginInsertRows(QModelIndex(), m_modems.size(), m_modems.size() + toAdd.size() - 1);
90 for (const auto& path: toAdd)
91 {
92- auto modem = std::make_shared<Modem>(path, m_propertyCache->connection(), m_sims, nullptr);
93+ auto modem = std::make_shared<Modem>(path, m_propertyCache->connection(), m_sims);
94 m_objectOwner(modem.get());
95 m_modems << modem;
96 connect(modem.get(), &Modem::simChanged, this, &Priv::simChanged);
97@@ -178,6 +178,9 @@
98 case Roles::RoleSerial:
99 return modem->serial();
100 break;
101+ case Roles::RoleModem:
102+ return QVariant::fromValue<Modem*>(modem.get());
103+ break;
104 case Roles::RoleSim:
105 return QVariant::fromValue<Sim*>(modem->sim());
106 break;
107
108=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.h'
109--- src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.h 2016-06-22 09:42:47 +0000
110+++ src/connectivity-api/connectivity-qt/connectivityqt/modems-list-model.h 2016-06-22 09:42:47 +0000
111@@ -49,6 +49,7 @@
112 {
113 RoleIndex = Qt::UserRole + 1,
114 RoleSerial,
115+ RoleModem,
116 RoleSim
117 };
118
119@@ -67,6 +68,7 @@
120 QHash<int, QByteArray> roles;
121 roles[RoleIndex] = "Index";
122 roles[RoleSerial] = "Serial";
123+ roles[RoleModem] = "Modem";
124 roles[RoleSim] = "Sim";
125 return roles;
126 }
127
128=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/sim.cpp'
129--- src/connectivity-api/connectivity-qt/connectivityqt/sim.cpp 2016-06-22 09:42:47 +0000
130+++ src/connectivity-api/connectivity-qt/connectivityqt/sim.cpp 2016-06-22 09:42:47 +0000
131@@ -50,11 +50,16 @@
132 } else if (name == "DataRoamingEnabled")
133 {
134 Q_EMIT p.dataRoamingEnabledChanged(value.toBool());
135+ } else if (name == "Imsi")
136+ {
137+ Q_EMIT p.imsiChanged(value.toString());
138+ } else if (name == "PrimaryPhoneNumber")
139+ {
140+ Q_EMIT p.primaryPhoneNumberChanged(value.toString());
141 } else {
142 qWarning() << "connectivityqt::Sim::Priv::propertyChanged(): "
143 << "Unexpected property: " << name;
144 }
145-
146 }
147
148 public:
149@@ -92,6 +97,11 @@
150 return QDBusObjectPath(d->m_simInterface->path());
151 }
152
153+QString Sim::iccid() const
154+{
155+ return d->m_propertyCache->get("Iccid").toString();
156+}
157+
158 QString Sim::imsi() const
159 {
160 return d->m_propertyCache->get("Imsi").toString();
161@@ -102,11 +112,6 @@
162 return d->m_propertyCache->get("PrimaryPhoneNumber").toString();
163 }
164
165-QList<QString> Sim::phoneNumbers() const
166-{
167- return d->m_propertyCache->get("PhoneNumbers").toStringList();
168-}
169-
170 bool Sim::locked() const
171 {
172 return d->m_propertyCache->get("Locked").toBool();
173
174=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/sim.h'
175--- src/connectivity-api/connectivity-qt/connectivityqt/sim.h 2016-06-22 09:42:47 +0000
176+++ src/connectivity-api/connectivity-qt/connectivityqt/sim.h 2016-06-22 09:42:47 +0000
177@@ -42,25 +42,25 @@
178 Q_PROPERTY(QDBusObjectPath path READ path)
179 QDBusObjectPath path() const;
180
181- Q_PROPERTY(QString Imsi READ imsi CONSTANT)
182+ Q_PROPERTY(QString Iccid READ iccid CONSTANT)
183+ QString iccid() const;
184+
185+ Q_PROPERTY(QString Imsi READ imsi NOTIFY imsiChanged)
186 QString imsi() const;
187
188- Q_PROPERTY(QString PrimaryPhoneNumber READ primaryPhoneNumber CONSTANT)
189+ Q_PROPERTY(QString PrimaryPhoneNumber READ primaryPhoneNumber NOTIFY primaryPhoneNumberChanged)
190 QString primaryPhoneNumber() const;
191
192- Q_PROPERTY(QList<QString> PhoneNumbers READ phoneNumbers CONSTANT)
193- QList<QString> phoneNumbers() const;
194-
195 Q_PROPERTY(bool Locked READ locked NOTIFY lockedChanged)
196 bool locked() const;
197
198 Q_PROPERTY(bool Present READ present NOTIFY presentChanged)
199 bool present() const;
200
201- Q_PROPERTY(QString Mcc READ mcc CONSTANT)
202+ Q_PROPERTY(QString Mcc READ mcc NOTIFY mccChanged)
203 QString mcc() const;
204
205- Q_PROPERTY(QString Mnc READ mnc CONSTANT)
206+ Q_PROPERTY(QString Mnc READ mnc NOTIFY mncChanged)
207 QString mnc() const;
208
209 Q_PROPERTY(QList<QString> PreferredLanguages READ preferredLanguages CONSTANT)
210@@ -78,7 +78,10 @@
211 void lockedChanged(bool value);
212 void presentChanged(bool value);
213 void dataRoamingEnabledChanged(bool value);
214-
215+ void imsiChanged(const QString &value);
216+ void primaryPhoneNumberChanged(const QString &value);
217+ void mccChanged(const QString &value);
218+ void mncChanged(const QString &value);
219
220 protected:
221 class Priv;
222
223=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.cpp'
224--- src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.cpp 2016-06-22 09:42:47 +0000
225+++ src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.cpp 2016-06-22 09:42:47 +0000
226@@ -82,6 +82,10 @@
227 connect(sim.get(), &Sim::lockedChanged, this, &Priv::lockedChanged);
228 connect(sim.get(), &Sim::presentChanged, this, &Priv::presentChanged);
229 connect(sim.get(), &Sim::dataRoamingEnabledChanged, this, &Priv::dataRoamingEnabledChanged);
230+ connect(sim.get(), &Sim::imsiChanged, this, &Priv::imsiChanged);
231+ connect(sim.get(), &Sim::primaryPhoneNumberChanged, this, &Priv::primaryPhoneNumberChanged);
232+ connect(sim.get(), &Sim::mccChanged, this, &Priv::mccChanged);
233+ connect(sim.get(), &Sim::mncChanged, this, &Priv::mncChanged);
234 }
235 p.endInsertRows();
236 }
237@@ -119,6 +123,26 @@
238 auto idx = findSim(sender());
239 p.dataChanged(idx, idx, {SimsListModel::Roles::RoleDataRoamingEnabled});
240 }
241+ void imsiChanged()
242+ {
243+ auto idx = findSim(sender());
244+ p.dataChanged(idx, idx, {SimsListModel::Roles::RoleImsi});
245+ }
246+ void primaryPhoneNumberChanged()
247+ {
248+ auto idx = findSim(sender());
249+ p.dataChanged(idx, idx, {SimsListModel::Roles::RolePrimaryPhoneNumber});
250+ }
251+ void mccChanged()
252+ {
253+ auto idx = findSim(sender());
254+ p.dataChanged(idx, idx, {SimsListModel::Roles::RoleMcc});
255+ }
256+ void mncChanged()
257+ {
258+ auto idx = findSim(sender());
259+ p.dataChanged(idx, idx, {SimsListModel::Roles::RoleMnc});
260+ }
261
262 void propertyChanged(const QString& name, const QVariant& value)
263 {
264@@ -183,15 +207,15 @@
265
266 switch (role)
267 {
268+ case Roles::RoleIccid:
269+ return sim->iccid();
270+ break;
271 case Roles::RoleImsi:
272 return sim->imsi();
273 break;
274 case Roles::RolePrimaryPhoneNumber:
275 return sim->primaryPhoneNumber();
276 break;
277- case Roles::RolePhoneNumbers:
278- return QVariant::fromValue<QStringList>(sim->phoneNumbers());
279- break;
280 case RoleLocked:
281 return sim->locked();
282 break;
283@@ -209,7 +233,7 @@
284 case Roles::RoleDataRoamingEnabled:
285 return sim->dataRoamingEnabled();
286 break;
287- case Roles::RoleSimObject:
288+ case Roles::RoleSim:
289 return QVariant::fromValue<Sim*>(sim.get());
290 break;
291 }
292
293=== modified file 'src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.h'
294--- src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.h 2016-06-22 09:42:47 +0000
295+++ src/connectivity-api/connectivity-qt/connectivityqt/sims-list-model.h 2016-06-22 09:42:47 +0000
296@@ -47,16 +47,16 @@
297
298 enum Roles
299 {
300- RoleImsi = Qt::UserRole + 1,
301+ RoleIccid = Qt::UserRole + 1,
302+ RoleImsi,
303 RolePrimaryPhoneNumber,
304- RolePhoneNumbers,
305 RoleLocked,
306 RolePresent,
307 RoleMcc,
308 RoleMnc,
309 RolePreferredLanguages,
310 RoleDataRoamingEnabled,
311- RoleSimObject
312+ RoleSim
313 };
314
315 SimsListModel(const internal::SimsListModelParameters& parameters);
316@@ -72,25 +72,22 @@
317 QHash<int, QByteArray> roleNames() const override
318 {
319 QHash<int, QByteArray> roles;
320+ roles[RoleIccid] = "Iccid";
321 roles[RoleImsi] = "Imsi";
322 roles[RolePrimaryPhoneNumber] = "PrimaryPhoneNumber";
323- roles[RolePhoneNumbers] = "PhoneNumbers";
324 roles[RoleLocked] = "Locked";
325 roles[RolePresent] = "Present";
326 roles[RoleMcc] = "Mcc";
327 roles[RoleMnc] = "Mnc";
328 roles[RolePreferredLanguages] = "PreferredLanguages";
329 roles[RoleDataRoamingEnabled] = "DataRoamingEnabled";
330- roles[RoleSimObject] = "SimObject";
331+ roles[RoleSim] = "Sim";
332 return roles;
333 }
334
335 Sim::SPtr getSimByPath(const QDBusObjectPath &path) const;
336
337-public Q_SLOTS:
338-
339 Q_SIGNALS:
340-
341 void simsUpdated();
342
343 protected:
344
345=== modified file 'src/indicator/connectivity-service/connectivity-service.cpp'
346--- src/indicator/connectivity-service/connectivity-service.cpp 2016-06-22 09:42:47 +0000
347+++ src/indicator/connectivity-service/connectivity-service.cpp 2016-06-22 09:42:47 +0000
348@@ -188,32 +188,37 @@
349
350 void updateSims()
351 {
352- auto current_imsis = m_sims.keys().toSet();
353+ auto current_iccids = m_sims.keys().toSet();
354+
355 QMap<QString, nmofono::wwan::Sim::Ptr> sims;
356 for (auto i : m_manager->sims())
357 {
358- sims[i->imsi()] = i;
359+ sims[i->iccid()] = i;
360 }
361 auto toAdd(sims.keys().toSet());
362- toAdd.subtract(current_imsis);
363+ toAdd.subtract(current_iccids);
364
365- auto toRemove(current_imsis);
366+ auto toRemove(current_iccids);
367 toRemove.subtract(sims.keys().toSet());
368
369- for (auto imsi : toRemove)
370- {
371- m_sims.remove(imsi);
372- }
373-
374- for (auto imsi : toAdd)
375- {
376- DBusSim::SPtr dbussim = make_shared<DBusSim>(sims[imsi], m_connection);
377- m_sims[imsi] = dbussim;
378- }
379-
380- notifyPrivateProperties({
381- "Sims"
382- });
383+ for (auto iccid : toRemove)
384+ {
385+ m_sims.remove(iccid);
386+ }
387+
388+ for (auto iccid : toAdd)
389+ {
390+ DBusSim::SPtr dbussim = make_shared<DBusSim>(sims[iccid], m_connection);
391+ m_sims[iccid] = dbussim;
392+ }
393+
394+ if (!toRemove.isEmpty() || !toAdd.isEmpty())
395+ {
396+ notifyPrivateProperties({
397+ "Sims"
398+ });
399+ flushProperties();
400+ }
401 }
402
403 void updateModems()
404@@ -244,9 +249,14 @@
405 updateModemSimPath(dbusmodem, m->sim());
406 connect(m.get(), &wwan::Modem::simUpdated, this, &Private::modemSimUpdated);
407 }
408- notifyPrivateProperties({
409- "Modems"
410- });
411+
412+ if (!toRemove.isEmpty() || !toAdd.isEmpty())
413+ {
414+ notifyPrivateProperties({
415+ "Modems"
416+ });
417+ flushProperties();
418+ }
419 }
420
421 void modemSimUpdated()
422@@ -259,11 +269,20 @@
423 {
424 if (!sim)
425 {
426- modem->setSim(QDBusObjectPath("/"));
427+ modem->setSim(QDBusObjectPath ("/"));
428 }
429 else
430 {
431- modem->setSim(m_sims[sim->imsi()]->path());
432+ if (m_sims.contains (sim->iccid()))
433+ {
434+ auto dbusSim = m_sims[sim->iccid()];
435+ modem->setSim(dbusSim->path());
436+ }
437+ else
438+ {
439+ qWarning() << "Could not find SIM with ICCID:"
440+ << sim->iccid();
441+ }
442 }
443 }
444
445@@ -634,8 +653,15 @@
446 return QDBusObjectPath("/");
447 }
448
449- Q_ASSERT(p.d->m_sims.contains(sim->imsi()));
450- return p.d->m_sims[sim->imsi()]->path();
451+ if (p.d->m_sims.contains(sim->iccid()))
452+ {
453+ return p.d->m_sims[sim->iccid()]->path();
454+ }
455+ else
456+ {
457+ qWarning() << "Could not find SIM for ICCID:" << sim->iccid();
458+ return QDBusObjectPath("/");
459+ }
460 }
461
462 void PrivateService::setSimForMobileData(const QDBusObjectPath &path)
463
464=== modified file 'src/indicator/connectivity-service/dbus-modem.cpp'
465--- src/indicator/connectivity-service/dbus-modem.cpp 2016-06-22 09:42:47 +0000
466+++ src/indicator/connectivity-service/dbus-modem.cpp 2016-06-22 09:42:47 +0000
467@@ -33,7 +33,7 @@
468 m_modem(modem),
469 m_connection(connection)
470 {
471- m_path.setPath(DBusTypes::modemPath(m_modem->serial()));
472+ m_path.setPath(DBusTypes::modemPath());
473
474 new ModemAdaptor(this);
475
476
477=== modified file 'src/indicator/connectivity-service/dbus-sim.cpp'
478--- src/indicator/connectivity-service/dbus-sim.cpp 2016-06-22 09:42:47 +0000
479+++ src/indicator/connectivity-service/dbus-sim.cpp 2016-06-22 09:42:47 +0000
480@@ -35,7 +35,7 @@
481 m_sim(sim),
482 m_connection(connection)
483 {
484- m_path.setPath(DBusTypes::simPath(m_sim->imsi()));
485+ m_path.setPath(DBusTypes::simPath());
486
487 new SimAdaptor(this);
488
489@@ -44,6 +44,10 @@
490 connect(sim.get(), &Sim::lockedChanged, this, &DBusSim::lockedChanged);
491 connect(sim.get(), &Sim::presentChanged, this, &DBusSim::presentChanged);
492 connect(sim.get(), &Sim::dataRoamingEnabledChanged, this, &DBusSim::dataRoamingEnabledChanged);
493+ connect(sim.get(), &Sim::imsiChanged, this, &DBusSim::imsiChanged);
494+ connect(sim.get(), &Sim::primaryPhoneNumberChanged, this, &DBusSim::primaryPhoneNumberChanged);
495+ connect(sim.get(), &Sim::mccChanged, this, &DBusSim::mccChanged);
496+ connect(sim.get(), &Sim::mncChanged, this, &DBusSim::mncChanged);
497 }
498
499 DBusSim::~DBusSim()
500@@ -74,6 +78,11 @@
501 );
502 }
503
504+QString DBusSim::iccid() const
505+{
506+ return m_sim->iccid();
507+}
508+
509 QString DBusSim::imsi() const
510 {
511 return m_sim->imsi();
512@@ -139,6 +148,26 @@
513 notifyProperties({"DataRoamingEnabled"});
514 }
515
516+void DBusSim::imsiChanged()
517+{
518+ notifyProperties({"Imsi"});
519+}
520+
521+void DBusSim::primaryPhoneNumberChanged()
522+{
523+ notifyProperties({"PrimaryPhoneNumber"});
524+}
525+
526+void DBusSim::mccChanged()
527+{
528+ notifyProperties({"Mcc"});
529+}
530+
531+void DBusSim::mncChanged()
532+{
533+ notifyProperties({"Mnc"});
534+}
535+
536 nmofono::wwan::Sim::Ptr DBusSim::sim() const
537 {
538 return m_sim;
539
540=== modified file 'src/indicator/connectivity-service/dbus-sim.h'
541--- src/indicator/connectivity-service/dbus-sim.h 2016-06-22 09:42:47 +0000
542+++ src/indicator/connectivity-service/dbus-sim.h 2016-06-22 09:42:47 +0000
543@@ -48,6 +48,9 @@
544
545 virtual ~DBusSim();
546
547+ Q_PROPERTY(QString Iccid READ iccid)
548+ QString iccid() const;
549+
550 Q_PROPERTY(QString Imsi READ imsi)
551 QString imsi() const;
552
553@@ -86,6 +89,10 @@
554 void lockedChanged();
555 void presentChanged();
556 void dataRoamingEnabledChanged();
557+ void imsiChanged();
558+ void primaryPhoneNumberChanged();
559+ void mccChanged();
560+ void mncChanged();
561
562 private:
563 void notifyProperties(const QStringList& propertyNames);
564
565=== modified file 'src/indicator/factory.cpp'
566--- src/indicator/factory.cpp 2016-06-22 09:42:47 +0000
567+++ src/indicator/factory.cpp 2016-06-22 09:42:47 +0000
568@@ -216,10 +216,10 @@
569 auto switch_r = s.get();
570 auto manager_r = manager.get();
571 QObject::connect(manager_r, &nmofono::Manager::flightModeUpdated, switch_r, [manager_r, switch_r](bool value) {
572- switch_r->setEnabled(!value && manager_r->simForMobileData());
573+ switch_r->setEnabled(!value && manager_r->simForMobileData() && manager_r->simForMobileData()->present());
574 });
575 QObject::connect(manager_r, &nmofono::Manager::simForMobileDataChanged, switch_r, [manager_r, switch_r]() {
576- switch_r->setEnabled(!manager_r->flightMode() && manager_r->simForMobileData());
577+ switch_r->setEnabled(!manager_r->flightMode() && manager_r->simForMobileData() && manager_r->simForMobileData()->present());
578 });
579
580 return s;
581
582=== modified file 'src/indicator/nmofono/connectivity-service-settings.cpp'
583--- src/indicator/nmofono/connectivity-service-settings.cpp 2016-06-22 09:42:47 +0000
584+++ src/indicator/nmofono/connectivity-service-settings.cpp 2016-06-22 09:42:47 +0000
585@@ -19,6 +19,7 @@
586
587 #include <nmofono/connectivity-service-settings.h>
588
589+using namespace std;
590 using namespace nmofono;
591
592 class ConnectivityServiceSettings::Private : public QObject
593@@ -27,16 +28,11 @@
594 public:
595
596 ConnectivityServiceSettings &p;
597- QSettings *m_settings;
598+ unique_ptr<QSettings> m_settings;
599
600 Private(ConnectivityServiceSettings &parent)
601 : p(parent)
602 {
603- m_settings = new QSettings(QSettings::IniFormat,
604- QSettings::UserScope,
605- "Ubuntu",
606- "connectivityservice",
607- this);
608 }
609
610 virtual ~Private()
611@@ -54,7 +50,19 @@
612 : QObject(parent),
613 d{new Private(*this)}
614 {
615-
616+ if (qEnvironmentVariableIsSet("INDICATOR_NETWORK_SETTINGS_PATH"))
617+ {
618+ // For testing only
619+ QString path = QString::fromUtf8(qgetenv("INDICATOR_NETWORK_SETTINGS_PATH")) + "/config.ini";
620+ d->m_settings = make_unique<QSettings>(path, QSettings::IniFormat);
621+ }
622+ else
623+ {
624+ d->m_settings = make_unique<QSettings>(QSettings::IniFormat,
625+ QSettings::UserScope,
626+ "connectivity-service",
627+ "config");
628+ }
629 }
630
631 ConnectivityServiceSettings::~ConnectivityServiceSettings()
632@@ -66,20 +74,20 @@
633 {
634 return d->m_settings->value("MobileDataEnabled");
635 }
636+
637 void ConnectivityServiceSettings::setMobileDataEnabled(bool value)
638 {
639 d->m_settings->setValue("MobileDataEnabled", value);
640- d->m_settings->sync();
641 }
642
643 QVariant ConnectivityServiceSettings::simForMobileData()
644 {
645 return d->m_settings->value("SimForMobileData");
646 }
647-void ConnectivityServiceSettings::setSimForMobileData(const QString &imsi)
648+
649+void ConnectivityServiceSettings::setSimForMobileData(const QString &iccid)
650 {
651- d->m_settings->setValue("SimForMobileData", imsi);
652- d->m_settings->sync();
653+ d->m_settings->setValue("SimForMobileData", iccid);
654 }
655
656 QStringList ConnectivityServiceSettings::knownSims()
657@@ -100,12 +108,12 @@
658 void ConnectivityServiceSettings::setKnownSims(const QStringList &list)
659 {
660 d->m_settings->setValue("KnownSims", QVariant(list));
661- d->m_settings->sync();
662 }
663
664-wwan::Sim::Ptr ConnectivityServiceSettings::createSimFromSettings(const QString &imsi)
665+wwan::Sim::Ptr ConnectivityServiceSettings::createSimFromSettings(const QString &iccid)
666 {
667- d->m_settings->beginGroup(QString("Sims/%1/").arg(imsi));
668+ d->m_settings->beginGroup(QString("Sims/%1/").arg(iccid));
669+ QVariant imsi_var = d->m_settings->value("Imsi");
670 QVariant primaryPhoneNumber_var = d->m_settings->value("PrimaryPhoneNumber");
671 QVariant mcc_var = d->m_settings->value("Mcc");
672 QVariant mnc_var = d->m_settings->value("Mnc");
673@@ -113,19 +121,21 @@
674 QVariant dataRoamingEnabled_var = d->m_settings->value("DataRoamingEnabled");
675 d->m_settings->endGroup();
676
677- if (imsi.isNull() ||
678+ if (iccid.isNull() ||
679+ imsi_var.isNull() ||
680 primaryPhoneNumber_var.isNull() ||
681 mcc_var.isNull() ||
682 mnc_var.isNull() ||
683 preferredLanguages_var.isNull() ||
684 dataRoamingEnabled_var.isNull())
685 {
686- qWarning() << "Corrupt settings for SIM: " << imsi;
687- d->m_settings->remove(QString("Sims/%1/").arg(imsi));
688+ qWarning() << "Corrupt settings for SIM: " << iccid;
689+ d->m_settings->remove(QString("Sims/%1/").arg(iccid));
690 return wwan::Sim::Ptr();
691 }
692
693- return wwan::Sim::Ptr(new wwan::Sim(imsi,
694+ return wwan::Sim::Ptr(new wwan::Sim(iccid,
695+ imsi_var.toString(),
696 primaryPhoneNumber_var.toString(),
697 mcc_var.toString(),
698 mnc_var.toString(),
699@@ -135,14 +145,14 @@
700
701 void ConnectivityServiceSettings::saveSimToSettings(wwan::Sim::Ptr sim)
702 {
703- d->m_settings->beginGroup(QString("Sims/%1/").arg(sim->imsi()));
704- d->m_settings->setValue("PrimaryPhoneNumber", QVariant(sim->primaryPhoneNumber()));
705+ d->m_settings->beginGroup(QString("Sims/%1/").arg(sim->iccid()));
706+ d->m_settings->setValue("Imsi", sim->imsi());
707+ d->m_settings->setValue("PrimaryPhoneNumber", sim->primaryPhoneNumber());
708 d->m_settings->setValue("Mcc", sim->mcc());
709 d->m_settings->setValue("Mnc", sim->mnc());
710 d->m_settings->setValue("PreferredLanguages", QVariant(sim->preferredLanguages()));
711 d->m_settings->setValue("DataRoamingEnabled", sim->dataRoamingEnabled());
712 d->m_settings->endGroup();
713- d->m_settings->sync();
714 }
715
716 #include "connectivity-service-settings.moc"
717
718=== modified file 'src/indicator/nmofono/connectivity-service-settings.h'
719--- src/indicator/nmofono/connectivity-service-settings.h 2016-06-22 09:42:47 +0000
720+++ src/indicator/nmofono/connectivity-service-settings.h 2016-06-22 09:42:47 +0000
721@@ -50,12 +50,12 @@
722 void setMobileDataEnabled(bool value);
723
724 QVariant simForMobileData();
725- void setSimForMobileData(const QString &imsi);
726+ void setSimForMobileData(const QString &iccid);
727
728 QStringList knownSims();
729 void setKnownSims(const QStringList &list);
730
731- wwan::Sim::Ptr createSimFromSettings(const QString &imsi);
732+ wwan::Sim::Ptr createSimFromSettings(const QString &iccid);
733 void saveSimToSettings(wwan::Sim::Ptr sim);
734
735 public Q_SLOTS:
736
737=== modified file 'src/indicator/nmofono/manager-impl.cpp'
738--- src/indicator/nmofono/manager-impl.cpp 2016-06-22 09:42:47 +0000
739+++ src/indicator/nmofono/manager-impl.cpp 2016-06-22 09:42:47 +0000
740@@ -96,58 +96,11 @@
741 Private(Manager& parent) :
742 p(parent)
743 {
744- m_settings = std::make_shared<ConnectivityServiceSettings>();
745-
746- m_simManager = make_shared<wwan::SimManager>(m_settings);
747- m_sims = m_simManager->knownSims();
748- connect(m_simManager.get(), &wwan::SimManager::simAdded, this, &Private::simAdded);
749-
750- QVariant ret = m_settings->mobileDataEnabled();
751- if (ret.isNull())
752- {
753- /* This is the first time we are running on a system.
754- *
755- * We need to figure out the status of mobile data from looking
756- * at the individual modems.
757- */
758- m_mobileDataEnabledPending = true;
759- m_settings->setMobileDataEnabled(false);
760- }
761- else
762- {
763- m_mobileDataEnabled = ret.toBool();
764- }
765-
766- ret = m_settings->simForMobileData();
767- if (ret.isNull())
768- {
769- /* This is the first time we are running on a system.
770- *
771- * We need to figure out the SIM used for mobile data
772- * from the individual modems.
773- */
774- m_simForMobileDataPending = true;
775- m_settings->setSimForMobileData(QString());
776- }
777- else
778- {
779- QString imsi = ret.toString();
780- wwan::Sim::Ptr sim;
781- for(auto i = m_sims.begin(); i != m_sims.end(); i++)
782- {
783- if ((*i)->imsi() == imsi) {
784- sim = *i;
785- break;
786- }
787- }
788- m_simForMobileData = sim;
789- }
790-
791 }
792
793 void matchModemsAndSims()
794 {
795- for (wwan::Modem::Ptr modem: m_modems)
796+ for (wwan::Modem::Ptr modem: m_ofonoLinks)
797 {
798 bool match = false;
799 for(wwan::Sim::Ptr sim : m_sims)
800@@ -169,8 +122,31 @@
801 void simAdded(wwan::Sim::Ptr sim)
802 {
803 m_sims.append(sim);
804- matchModemsAndSims();
805+ connect(sim.get(), &wwan::Sim::presentChanged, this, &Private::matchModemsAndSims);
806 Q_EMIT p.simsChanged();
807+ matchModemsAndSims();
808+ }
809+
810+ void initialDataOnSet()
811+ {
812+ wwan::Sim *sim_raw = qobject_cast<wwan::Sim*>(sender());
813+ if (!sim_raw)
814+ {
815+ Q_ASSERT(0);
816+ return;
817+ }
818+ wwan::Sim::Ptr sim = sim_raw->shared_from_this();
819+
820+ if (!m_mobileDataEnabledPending && !m_simForMobileDataPending)
821+ {
822+ return;
823+ }
824+
825+ if (sim->initialDataOn())
826+ {
827+ setMobileDataEnabled(true);
828+ setSimForMobileData(sim);
829+ }
830 }
831
832 void modemReady()
833@@ -181,8 +157,21 @@
834 Q_ASSERT(0);
835 return;
836 }
837- m_modems.append(m_ofonoLinks[modem_raw->name()]);
838- matchModemsAndSims();
839+ auto modem = m_ofonoLinks[modem_raw->name()];
840+ if (!modem->sim())
841+ {
842+ matchModemsAndSims();
843+ }
844+
845+ if (m_mobileDataEnabledPending || m_simForMobileDataPending)
846+ {
847+ connect(modem->sim().get(), &wwan::Sim::initialDataOnSet, this, &Private::initialDataOnSet);
848+ if (modem->sim()->initialDataOn())
849+ {
850+ modem->sim()->initialDataOnSet();
851+ }
852+ }
853+ m_modems.append(modem);
854 Q_EMIT p.modemsChanged();
855 }
856
857@@ -197,6 +186,50 @@
858 Q_EMIT p.unstoppableOperationHappeningUpdated(m_unstoppableOperationHappening);
859 }
860
861+ void loadSettings()
862+ {
863+ QVariant ret = m_settings->mobileDataEnabled();
864+ if (ret.isNull())
865+ {
866+ /* This is the first time we are running on a system.
867+ *
868+ * We need to figure out the status of mobile data from looking
869+ * at the individual modems.
870+ */
871+ m_mobileDataEnabledPending = true;
872+ m_settings->setMobileDataEnabled(false);
873+ }
874+ else
875+ {
876+ setMobileDataEnabled(ret.toBool());
877+ }
878+
879+ ret = m_settings->simForMobileData();
880+ if (ret.isNull())
881+ {
882+ /* This is the first time we are running on a system.
883+ *
884+ * We need to figure out the SIM used for mobile data
885+ * from the individual modems.
886+ */
887+ m_simForMobileDataPending = true;
888+ m_settings->setSimForMobileData(QString());
889+ }
890+ else
891+ {
892+ QString iccid = ret.toString();
893+ wwan::Sim::Ptr sim;
894+ for(auto i = m_sims.begin(); i != m_sims.end(); i++)
895+ {
896+ if ((*i)->iccid() == iccid) {
897+ sim = *i;
898+ break;
899+ }
900+ }
901+ setSimForMobileData(sim);
902+ }
903+ }
904+
905 public Q_SLOTS:
906 void updateHasWifi()
907 {
908@@ -316,7 +349,6 @@
909 m_ofonoLinks[path] = modem;
910 connect(modem.get(), &wwan::Modem::readyToUnlock, this, &Private::modemReadyToUnlock);
911 connect(modem.get(), &wwan::Modem::ready, this, &Private::modemReady);
912- matchModemsAndSims();
913 }
914
915 Q_EMIT p.linksUpdated();
916@@ -326,10 +358,11 @@
917 }
918
919 void setMobileDataEnabled(bool value) {
920- if (m_mobileDataEnabled == value)
921+ if (m_mobileDataEnabled == value && !m_mobileDataEnabledPending)
922 {
923 return;
924 }
925+ m_mobileDataEnabledPending = false;
926
927 m_settings->setMobileDataEnabled(value);
928 m_mobileDataEnabled = value;
929@@ -357,10 +390,14 @@
930 }
931
932 void setSimForMobileData(wwan::Sim::Ptr sim) {
933- if (m_simForMobileData == sim)
934+ if (m_simForMobileData == sim && !m_simForMobileDataPending)
935 {
936 return;
937 }
938+ if (m_simForMobileDataPending) {
939+ m_simForMobileDataPending = false;
940+ setMobileDataEnabled(m_mobileDataEnabled);
941+ }
942
943 if (m_simForMobileData)
944 {
945@@ -373,14 +410,14 @@
946 }
947 else
948 {
949- m_settings->setSimForMobileData(sim->imsi());
950+ m_settings->setSimForMobileData(sim->iccid());
951 }
952
953
954 m_simForMobileData = sim;
955 if (m_simForMobileData)
956 {
957- m_simForMobileData->setMobileDataEnabled(p.mobileDataEnabled());
958+ m_simForMobileData->setMobileDataEnabled(m_mobileDataEnabled);
959 }
960
961 Q_EMIT p.simForMobileDataChanged();
962@@ -428,6 +465,17 @@
963 connect(d->m_unlockDialog.get(), &SimUnlockDialog::ready, d.get(), &Private::sim_unlock_ready);
964
965 d->m_ofono = make_shared<QOfonoManager>();
966+
967+ // Load the SIM manager before we connect to the signals
968+ d->m_settings = make_shared<ConnectivityServiceSettings>();
969+ d->m_simManager = make_shared<wwan::SimManager>(d->m_ofono, d->m_settings);
970+ connect(d->m_simManager.get(), &wwan::SimManager::simAdded, d.get(), &Private::simAdded);
971+ d->m_sims = d->m_simManager->knownSims();
972+ for (auto sim : d->m_sims)
973+ {
974+ connect(sim.get(), &wwan::Sim::presentChanged, d.get(), &Private::matchModemsAndSims);
975+ }
976+
977 connect(d->m_ofono.get(), &QOfonoManager::modemsChanged, d.get(), &Private::modems_changed);
978 d->modems_changed(d->m_ofono->modems());
979
980@@ -460,6 +508,8 @@
981 /// @todo set by the default connections.
982 d->m_characteristics = Link::Characteristics::empty;
983
984+ d->loadSettings();
985+
986 d->updateHasWifi();
987 }
988
989
990=== modified file 'src/indicator/nmofono/wwan/modem.cpp'
991--- src/indicator/nmofono/wwan/modem.cpp 2016-06-22 09:42:47 +0000
992+++ src/indicator/nmofono/wwan/modem.cpp 2016-06-22 09:42:47 +0000
993@@ -99,6 +99,8 @@
994
995 QString m_serial;
996 bool m_serialSet = false;
997+ bool m_presentSet = false;
998+ bool m_present = false;
999 bool m_readyFired = false;
1000
1001 QString m_operatorName;
1002@@ -169,6 +171,19 @@
1003
1004 if (m_serialSet && !m_readyFired)
1005 {
1006+ if (!m_simManager)
1007+ {
1008+ return;
1009+ }
1010+
1011+ if (!m_sim)
1012+ {
1013+ if (!m_presentSet)
1014+ {
1015+ return;
1016+ }
1017+ }
1018+
1019 m_readyFired = true;
1020 Q_EMIT p.ready();
1021 }
1022@@ -267,11 +282,22 @@
1023 connect(m_simManager.get(),
1024 &QOfonoSimManager::resetPinComplete, this,
1025 &Private::resetPinComplete);
1026+
1027+ connect(m_simManager.get(),
1028+ &QOfonoSimManager::presenceChanged, this,
1029+ &Private::presentChanged);
1030 }
1031
1032 update();
1033 }
1034
1035+ void presentChanged()
1036+ {
1037+ m_presentSet = true;
1038+ m_present = m_simManager->present();
1039+ update();
1040+ }
1041+
1042 void update()
1043 {
1044 setOnline(m_ofonoModem->online());
1045@@ -781,6 +807,7 @@
1046 }
1047 d->m_sim = sim;
1048 Q_EMIT simUpdated();
1049+ d->update();
1050 }
1051
1052 QString
1053
1054=== modified file 'src/indicator/nmofono/wwan/qofono-sim-wrapper.cpp'
1055--- src/indicator/nmofono/wwan/qofono-sim-wrapper.cpp 2016-06-22 09:42:47 +0000
1056+++ src/indicator/nmofono/wwan/qofono-sim-wrapper.cpp 2016-06-22 09:42:47 +0000
1057@@ -41,18 +41,12 @@
1058 QOfonoSimWrapper& p;
1059 shared_ptr<QOfonoSimManager> m_simManager;
1060
1061- QString m_imsi;
1062- QStringList m_phoneNumbers;
1063- QString m_mcc;
1064- QString m_mnc;
1065+ QString m_iccid;
1066 QStringList m_preferredLanguages;
1067
1068 bool m_present = false;
1069
1070- bool m_imsiSet = false;
1071- bool m_phoneNumbersSet = false;
1072- bool m_mccSet = false;
1073- bool m_mncSet = false;
1074+ bool m_iccidSet = false;
1075 bool m_preferredLanguagesSet = false;
1076
1077
1078@@ -60,10 +54,7 @@
1079 : p(parent), m_simManager{simmgr}
1080 {
1081 connect(simmgr.get(), &QOfonoSimManager::presenceChanged, this, &Private::presentChanged);
1082- connect(simmgr.get(), &QOfonoSimManager::subscriberIdentityChanged, this, &Private::imsiChanged);
1083- connect(simmgr.get(), &QOfonoSimManager::mobileCountryCodeChanged, this, &Private::mccChanged);
1084- connect(simmgr.get(), &QOfonoSimManager::mobileNetworkCodeChanged, this, &Private::mncChanged);
1085- connect(simmgr.get(), &QOfonoSimManager::subscriberNumbersChanged, this, &Private::phoneNumbersChanged);
1086+ connect(simmgr.get(), &QOfonoSimManager::cardIdentifierChanged, this, &Private::iccidChanged);
1087 connect(simmgr.get(), &QOfonoSimManager::preferredLanguagesChanged, this, &Private::preferredLanguagesChanged);
1088 }
1089
1090@@ -78,92 +69,27 @@
1091 m_present = value;
1092 if (!m_present)
1093 {
1094- m_imsiSet = false;
1095- m_phoneNumbersSet = false;
1096- m_mccSet = false;
1097- m_mncSet = false;
1098+ m_iccidSet = false;
1099 m_preferredLanguagesSet = false;
1100 Q_EMIT p.readyChanged(false);
1101 }
1102 Q_EMIT p.presentChanged(value);
1103 }
1104
1105- void imsiChanged(const QString &value)
1106- {
1107- if (value.isEmpty())
1108- {
1109- return;
1110- }
1111-
1112- if (m_imsiSet)
1113- {
1114- qWarning() << "Unexpected update on IMSI: " << m_imsi << ", " << value;
1115- }
1116-
1117- m_imsi = value;
1118- m_imsiSet = true;
1119- if (p.ready())
1120- {
1121- Q_EMIT p.readyChanged(true);
1122- }
1123- }
1124-
1125- void mccChanged(const QString &value)
1126- {
1127- if (value.isEmpty())
1128- {
1129- return;
1130- }
1131-
1132- if (m_mccSet)
1133- {
1134- qWarning() << "Unexpected update on MCC: " << m_mcc << ", " << value;
1135- }
1136-
1137-
1138- m_mcc = value;
1139- m_mccSet = true;
1140- if (p.ready())
1141- {
1142- Q_EMIT p.readyChanged(true);
1143- }
1144- }
1145-
1146- void mncChanged(const QString &value)
1147- {
1148- if (value.isEmpty())
1149- {
1150- return;
1151- }
1152-
1153- if (m_mncSet)
1154- {
1155- qWarning() << "Unexpected update on MNC: " << m_mnc << ", " << value;
1156- }
1157-
1158- m_mnc = value;
1159- m_mncSet = true;
1160- if (p.ready())
1161- {
1162- Q_EMIT p.readyChanged(true);
1163- }
1164- }
1165-
1166- void phoneNumbersChanged(const QStringList &value)
1167- {
1168- if (value.isEmpty())
1169- {
1170- return;
1171- }
1172-
1173- if (m_phoneNumbersSet)
1174- {
1175- qWarning() << "Unexpected update on Phone Numbers: " << m_phoneNumbers << ", " << value;
1176- }
1177-
1178-
1179- m_phoneNumbers = value;
1180- m_phoneNumbersSet = true;
1181+ void iccidChanged(const QString &value)
1182+ {
1183+ if (value.isEmpty())
1184+ {
1185+ return;
1186+ }
1187+
1188+ if (m_iccidSet)
1189+ {
1190+ qWarning() << "Unexpected update on ICCID: " << m_iccid << ", " << value;
1191+ }
1192+
1193+ m_iccid = value;
1194+ m_iccidSet = true;
1195 if (p.ready())
1196 {
1197 Q_EMIT p.readyChanged(true);
1198@@ -202,9 +128,9 @@
1199 QOfonoSimWrapper::~QOfonoSimWrapper()
1200 {}
1201
1202-QString QOfonoSimWrapper::imsi() const
1203+QString QOfonoSimWrapper::iccid() const
1204 {
1205- return d->m_imsi;
1206+ return d->m_iccid;
1207 }
1208
1209 bool QOfonoSimWrapper::present() const
1210@@ -212,20 +138,6 @@
1211 return d->m_present;
1212 }
1213
1214-QString QOfonoSimWrapper::mcc() const
1215-{
1216- return d->m_mcc;
1217-}
1218-
1219-QString QOfonoSimWrapper::mnc() const
1220-{
1221- return d->m_mnc;
1222-}
1223-
1224-QStringList QOfonoSimWrapper::phoneNumbers() const
1225-{
1226- return d->m_phoneNumbers;
1227-}
1228
1229 QStringList QOfonoSimWrapper::preferredLanguages() const
1230 {
1231@@ -233,10 +145,7 @@
1232 }
1233
1234 bool QOfonoSimWrapper::ready() const {
1235- return d->m_imsiSet &&
1236- d->m_phoneNumbersSet &&
1237- d->m_mccSet &&
1238- d->m_mncSet &&
1239+ return d->m_iccidSet &&
1240 d->m_preferredLanguagesSet;
1241 }
1242
1243
1244=== modified file 'src/indicator/nmofono/wwan/qofono-sim-wrapper.h'
1245--- src/indicator/nmofono/wwan/qofono-sim-wrapper.h 2016-06-22 09:42:47 +0000
1246+++ src/indicator/nmofono/wwan/qofono-sim-wrapper.h 2016-06-22 09:42:47 +0000
1247@@ -56,11 +56,8 @@
1248 QOfonoSimWrapper(std::shared_ptr<QOfonoSimManager> simmgr);
1249 ~QOfonoSimWrapper();
1250
1251- QString imsi() const;
1252+ QString iccid() const;
1253 bool present() const;
1254- QString mcc() const;
1255- QString mnc() const;
1256- QStringList phoneNumbers() const;
1257 QStringList preferredLanguages() const;
1258 bool ready() const;
1259
1260
1261=== modified file 'src/indicator/nmofono/wwan/sim-manager.cpp'
1262--- src/indicator/nmofono/wwan/sim-manager.cpp 2016-06-22 09:42:47 +0000
1263+++ src/indicator/nmofono/wwan/sim-manager.cpp 2016-06-22 09:42:47 +0000
1264@@ -55,24 +55,9 @@
1265
1266 ConnectivityServiceSettings::Ptr m_settings;
1267
1268- Private(SimManager& parent, ConnectivityServiceSettings::Ptr settings)
1269- : p(parent),
1270- m_settings(settings)
1271+ Private(SimManager& parent)
1272+ : p(parent)
1273 {
1274- QStringList imsis = m_settings->knownSims();
1275- for(auto imsi : imsis) {
1276- auto sim = m_settings->createSimFromSettings(imsi);
1277- connect(sim.get(), &Sim::dataRoamingEnabledChanged, this, &Private::simDataRoamingEnabledChanged);
1278- if (!sim)
1279- {
1280- continue;
1281- }
1282- m_knownSims[sim->imsi()] = sim;
1283- }
1284-
1285- m_ofono = make_shared<QOfonoManager>();
1286- connect(m_ofono.get(), &QOfonoManager::modemsChanged, this, &Private::modemsChanged);
1287- modemsChanged(m_ofono->modems());
1288 }
1289
1290 public Q_SLOTS:
1291@@ -99,9 +84,9 @@
1292 if (m_wrappers.contains(path))
1293 {
1294 auto wrapper = m_wrappers[path];
1295- if (m_knownSims.contains(wrapper->imsi()))
1296+ if (m_knownSims.contains(wrapper->iccid()))
1297 {
1298- auto sim = m_knownSims[wrapper->imsi()];
1299+ auto sim = m_knownSims[wrapper->iccid()];
1300 sim->setOfonoSimManager(std::shared_ptr<QOfonoSimManager>());
1301 }
1302 m_wrappers.remove(path);
1303@@ -153,9 +138,9 @@
1304 if (m_wrappers.contains(modem->modemPath()))
1305 {
1306 auto wrapper = m_wrappers[modem->modemPath()];
1307- if (m_knownSims.contains(wrapper->imsi()))
1308+ if (m_knownSims.contains(wrapper->iccid()))
1309 {
1310- auto sim = m_knownSims[wrapper->imsi()];
1311+ auto sim = m_knownSims[wrapper->iccid()];
1312 sim->setOfonoSimManager(std::shared_ptr<QOfonoSimManager>());
1313 }
1314 m_wrappers.remove(modem->modemPath());
1315@@ -174,9 +159,9 @@
1316
1317 if (!present)
1318 {
1319- if (m_knownSims.contains(wrapper->imsi()))
1320+ if (m_knownSims.contains(wrapper->iccid()))
1321 {
1322- auto sim = m_knownSims[wrapper->imsi()];
1323+ auto sim = m_knownSims[wrapper->iccid()];
1324 sim->setOfonoSimManager(std::shared_ptr<QOfonoSimManager>());
1325 }
1326 }
1327@@ -200,7 +185,7 @@
1328 bool found = false;
1329 for (auto i : m_knownSims.values())
1330 {
1331- if (wrapper->imsi() == i->imsi())
1332+ if (wrapper->iccid() == i->iccid())
1333 {
1334 found = true;
1335 i->setOfonoSimManager(wrapper->ofonoSimManager());
1336@@ -212,7 +197,7 @@
1337 auto sim = Sim::fromQOfonoSimWrapper(wrapper);
1338 connect(sim.get(), &Sim::dataRoamingEnabledChanged, this, &Private::simDataRoamingEnabledChanged);
1339 m_settings->saveSimToSettings(sim);
1340- m_knownSims[sim->imsi()] = sim;
1341+ m_knownSims[sim->iccid()] = sim;
1342 m_settings->setKnownSims(m_knownSims.keys());
1343 Q_EMIT p.simAdded(sim);
1344 }
1345@@ -228,22 +213,37 @@
1346 Q_ASSERT(0);
1347 return;
1348 }
1349- auto sim = m_knownSims[sim_raw->imsi()];
1350+ if (!m_knownSims.contains(sim_raw->iccid()))
1351+ {
1352+ Q_ASSERT(0);
1353+ return;
1354+ }
1355+ m_settings->saveSimToSettings(m_knownSims[sim_raw->iccid()]);
1356+ }
1357+
1358+};
1359+
1360+
1361+
1362+SimManager::SimManager(shared_ptr<QOfonoManager> ofono, ConnectivityServiceSettings::Ptr settings)
1363+ : d{new Private(*this)}
1364+{
1365+ d->m_ofono = ofono;
1366+ d->m_settings = settings;
1367+
1368+ QStringList iccids = d->m_settings->knownSims();
1369+ for(auto iccid : iccids) {
1370+ auto sim = d->m_settings->createSimFromSettings(iccid);
1371+ connect(sim.get(), &Sim::dataRoamingEnabledChanged, d.get(), &Private::simDataRoamingEnabledChanged);
1372 if (!sim)
1373 {
1374- Q_ASSERT(0);
1375- return;
1376+ continue;
1377 }
1378- m_settings->saveSimToSettings(sim);
1379+ d->m_knownSims[sim->iccid()] = sim;
1380 }
1381
1382-};
1383-
1384-
1385-
1386-SimManager::SimManager(ConnectivityServiceSettings::Ptr settings)
1387- : d{new Private(*this, settings)}
1388-{
1389+ connect(d->m_ofono.get(), &QOfonoManager::modemsChanged, d.get(), &Private::modemsChanged);
1390+ d->modemsChanged(d->m_ofono->modems());
1391 }
1392
1393 SimManager::~SimManager()
1394
1395=== modified file 'src/indicator/nmofono/wwan/sim-manager.h'
1396--- src/indicator/nmofono/wwan/sim-manager.h 2016-06-22 09:42:47 +0000
1397+++ src/indicator/nmofono/wwan/sim-manager.h 2016-06-22 09:42:47 +0000
1398@@ -27,6 +27,8 @@
1399 #include "sim.h"
1400 #include <nmofono/connectivity-service-settings.h>
1401
1402+class QOfonoManager;
1403+
1404 namespace nmofono
1405 {
1406 namespace wwan
1407@@ -44,7 +46,7 @@
1408 typedef std::shared_ptr<SimManager> Ptr;
1409 typedef std::weak_ptr<SimManager> WeakPtr;
1410
1411- SimManager(ConnectivityServiceSettings::Ptr settings);
1412+ SimManager(std::shared_ptr<QOfonoManager> ofono, ConnectivityServiceSettings::Ptr settings);
1413 ~SimManager();
1414
1415 QList<Sim::Ptr> knownSims() const;
1416
1417=== modified file 'src/indicator/nmofono/wwan/sim.cpp'
1418--- src/indicator/nmofono/wwan/sim.cpp 2016-06-22 09:42:47 +0000
1419+++ src/indicator/nmofono/wwan/sim.cpp 2016-06-22 09:42:47 +0000
1420@@ -38,10 +38,11 @@
1421
1422 Sim::Ptr Sim::fromQOfonoSimWrapper(const QOfonoSimWrapper *wrapper)
1423 {
1424- auto sim = Sim::Ptr(new Sim(wrapper->imsi(),
1425- wrapper->phoneNumbers().first(), // default to the first number
1426- wrapper->mcc(),
1427- wrapper->mnc(),
1428+ auto sim = Sim::Ptr(new Sim(wrapper->iccid(),
1429+ "",
1430+ "",
1431+ "",
1432+ "",
1433 wrapper->preferredLanguages(),
1434 false));
1435 sim->setOfonoSimManager(wrapper->ofonoSimManager());
1436@@ -65,16 +66,21 @@
1437
1438 QSet<QString> m_interfaces;
1439
1440+ QString m_iccid;
1441 QString m_imsi;
1442+ QStringList m_phoneNumbers;
1443 QString m_primaryPhoneNumber;
1444 QString m_mcc;
1445 QString m_mnc;
1446 QStringList m_preferredLanguages;
1447- bool m_dataRoamingEnabled;
1448+ bool m_dataRoamingEnabled = false;
1449 bool m_mobileDataEnabled = false;
1450
1451 bool m_locked = false;
1452
1453+ bool m_initialData = false;
1454+ bool m_initialDataSet = false;
1455+
1456 Private(Sim &parent)
1457 : p(parent)
1458 {
1459@@ -104,12 +110,81 @@
1460 }
1461
1462 m_simManager = simmgr;
1463+
1464+ if (simmgr)
1465+ {
1466+ connect(simmgr.get(), &QOfonoSimManager::subscriberIdentityChanged, this, &Private::imsiChanged);
1467+ connect(simmgr.get(), &QOfonoSimManager::subscriberNumbersChanged, this, &Private::phoneNumbersChanged);
1468+ connect(simmgr.get(), &QOfonoSimManager::mobileCountryCodeChanged, this, &Private::mccChanged);
1469+ connect(simmgr.get(), &QOfonoSimManager::mobileNetworkCodeChanged, this, &Private::mncChanged);
1470+ imsiChanged(simmgr->subscriberIdentity());
1471+ phoneNumbersChanged(simmgr->subscriberNumbers());
1472+ mccChanged(simmgr->mobileCountryCode());
1473+ mncChanged(simmgr->mobileNetworkCode());
1474+ }
1475 update();
1476
1477 Q_EMIT p.presentChanged(m_simManager.get() != nullptr);
1478 }
1479
1480- void connManagerChanged(shared_ptr<QOfonoConnectionManager> connmgr)
1481+ void phoneNumbersChanged(const QStringList &value)
1482+ {
1483+ if (value.isEmpty())
1484+ {
1485+ return;
1486+ }
1487+
1488+ m_phoneNumbers = value;
1489+ m_primaryPhoneNumber = value[0];
1490+ Q_EMIT p.primaryPhoneNumberChanged(m_primaryPhoneNumber);
1491+ }
1492+
1493+ void imsiChanged(const QString &value)
1494+ {
1495+ if (value.isEmpty())
1496+ {
1497+ return;
1498+ }
1499+
1500+ m_imsi = value;
1501+ Q_EMIT p.imsiChanged(m_imsi);
1502+ }
1503+
1504+ void mccChanged(const QString &value)
1505+ {
1506+ if (value.isEmpty())
1507+ {
1508+ return;
1509+ }
1510+
1511+ m_mcc = value;
1512+ Q_EMIT p.mccChanged(m_mcc);
1513+ }
1514+
1515+ void mncChanged(const QString &value)
1516+ {
1517+ if (value.isEmpty())
1518+ {
1519+ return;
1520+ }
1521+
1522+ m_mnc = value;
1523+ Q_EMIT p.mncChanged(m_mnc);
1524+ }
1525+
1526+ void poweredChanged()
1527+ {
1528+ if (!m_initialDataSet)
1529+ {
1530+ m_initialDataSet = true;
1531+ m_initialData = m_connManager->powered();
1532+ Q_EMIT p.initialDataOnSet();
1533+ m_connManager->setPowered(m_mobileDataEnabled);
1534+ }
1535+ update();
1536+ }
1537+
1538+ void setConnManager(shared_ptr<QOfonoConnectionManager> connmgr)
1539 {
1540 if (m_connManager == connmgr)
1541 {
1542@@ -121,7 +196,7 @@
1543 {
1544 connect(m_connManager.get(),
1545 &QOfonoConnectionManager::poweredChanged, this,
1546- &Private::update);
1547+ &Private::poweredChanged);
1548 connect(m_connManager.get(),
1549 &QOfonoConnectionManager::roamingAllowedChanged, this,
1550 &Private::update);
1551@@ -170,26 +245,26 @@
1552 Q_EMIT p.simIdentifierUpdated(m_simIdentifier);
1553 }
1554
1555- void setOfono(std::shared_ptr<QOfonoSimManager> simmgr)
1556+ void setOfono(shared_ptr<QOfonoSimManager> simmgr)
1557 {
1558 simManagerChanged(simmgr);
1559 if (simmgr)
1560 {
1561- m_connManager = std::make_shared<QOfonoConnectionManager>(this);
1562- m_connManager->setModemPath(simmgr->modemPath());
1563- connManagerChanged(m_connManager);
1564+ auto connManager = make_shared<QOfonoConnectionManager>(this);
1565+ connManager->setModemPath(simmgr->modemPath());
1566+ setConnManager(connManager);
1567 }
1568 else
1569 {
1570- m_connManager = std::shared_ptr<QOfonoConnectionManager>();
1571- connManagerChanged(m_connManager);
1572+ setConnManager(shared_ptr<QOfonoConnectionManager>());
1573 }
1574 }
1575
1576
1577 };
1578
1579-Sim::Sim(const QString &imsi,
1580+Sim::Sim(const QString &iccid,
1581+ const QString &imsi,
1582 const QString &primaryPhoneNumber,
1583 const QString &mcc,
1584 const QString &mnc,
1585@@ -197,6 +272,7 @@
1586 bool dataRoamingEnabled)
1587 : d{new Private(*this)}
1588 {
1589+ d->m_iccid = iccid;
1590 d->m_imsi = imsi;
1591 d->m_primaryPhoneNumber = primaryPhoneNumber;
1592 d->m_mcc = mcc;
1593@@ -214,6 +290,11 @@
1594 return d->m_simIdentifier;
1595 }
1596
1597+QString Sim::iccid() const
1598+{
1599+ return d->m_iccid;
1600+}
1601+
1602 QString Sim::imsi() const
1603 {
1604 return d->m_imsi;
1605@@ -261,6 +342,10 @@
1606 return;
1607 }
1608 d->m_dataRoamingEnabled = value;
1609+ if (d->m_connManager)
1610+ {
1611+ d->m_connManager->setRoamingAllowed(d->m_dataRoamingEnabled);
1612+ }
1613 Q_EMIT dataRoamingEnabledChanged(value);
1614 }
1615
1616@@ -302,6 +387,11 @@
1617 d->setOfono(simmgr);
1618 }
1619
1620+bool Sim::initialDataOn() const
1621+{
1622+ return d->m_initialData;
1623+}
1624+
1625
1626 }
1627 }
1628
1629=== modified file 'src/indicator/nmofono/wwan/sim.h'
1630--- src/indicator/nmofono/wwan/sim.h 2016-06-22 09:42:47 +0000
1631+++ src/indicator/nmofono/wwan/sim.h 2016-06-22 09:42:47 +0000
1632@@ -41,7 +41,7 @@
1633 namespace wwan
1634 {
1635
1636-class Sim : public QObject
1637+class Sim : public QObject, public std::enable_shared_from_this<Sim>
1638 {
1639 Q_OBJECT
1640
1641@@ -60,7 +60,8 @@
1642 static Sim::Ptr fromQOfonoSimWrapper(const QOfonoSimWrapper *wrapper);
1643
1644 private:
1645- Sim(const QString &imsi,
1646+ Sim(const QString &iccid,
1647+ const QString &imsi,
1648 const QString &primaryPhoneNumber,
1649 const QString &mcc,
1650 const QString &mnc,
1651@@ -74,10 +75,13 @@
1652 Q_PROPERTY(QString simIdentifier READ simIdentifier NOTIFY simIdentifierUpdated)
1653 const QString &simIdentifier() const;
1654
1655- Q_PROPERTY(QString imsi READ imsi CONSTANT)
1656+ Q_PROPERTY(QString iccid READ iccid CONSTANT)
1657+ QString iccid() const;
1658+
1659+ Q_PROPERTY(QString imsi READ imsi NOTIFY imsiChanged)
1660 QString imsi() const;
1661
1662- Q_PROPERTY(QString primaryPhoneNumber READ primaryPhoneNumber CONSTANT)
1663+ Q_PROPERTY(QString primaryPhoneNumber READ primaryPhoneNumber NOTIFY primaryPhoneNumberChanged)
1664 QString primaryPhoneNumber() const;
1665
1666 Q_PROPERTY(bool locked READ locked NOTIFY lockedChanged)
1667@@ -86,10 +90,10 @@
1668 Q_PROPERTY(bool present READ present NOTIFY presentChanged)
1669 bool present() const;
1670
1671- Q_PROPERTY(QString mcc READ mcc CONSTANT)
1672+ Q_PROPERTY(QString mcc READ mcc NOTIFY mccChanged)
1673 QString mcc() const;
1674
1675- Q_PROPERTY(QString mnc READ mnc CONSTANT)
1676+ Q_PROPERTY(QString mnc READ mnc NOTIFY mncChanged)
1677 QString mnc() const;
1678
1679 Q_PROPERTY(QList<QString> preferredLanguages READ preferredLanguages CONSTANT)
1680@@ -105,6 +109,8 @@
1681
1682 QString ofonoPath() const;
1683
1684+ bool initialDataOn() const;
1685+
1686 public Q_SLOTS:
1687 void unlock();
1688
1689@@ -112,6 +118,14 @@
1690
1691 void simIdentifierUpdated(const QString &);
1692
1693+ void imsiChanged(const QString &);
1694+
1695+ void primaryPhoneNumberChanged(const QString &);
1696+
1697+ void mccChanged(const QString &);
1698+
1699+ void mncChanged(const QString &);
1700+
1701 void lockedChanged(bool value);
1702
1703 void presentChanged(bool value);
1704@@ -119,6 +133,8 @@
1705 void dataRoamingEnabledChanged(bool value);
1706
1707 void mobileDataEnabledChanged(bool value);
1708+
1709+ void initialDataOnSet();
1710 };
1711
1712 }
1713
1714=== modified file 'src/qdbus-stubs/dbus-types.h'
1715--- src/qdbus-stubs/dbus-types.h 2016-06-22 09:42:47 +0000
1716+++ src/qdbus-stubs/dbus-types.h 2016-06-22 09:42:47 +0000
1717@@ -47,16 +47,18 @@
1718 return path.arg(counter++);
1719 }
1720
1721- inline QString modemPath(const QString &serial)
1722+ inline QString modemPath()
1723 {
1724+ static int counter {0};
1725 static QString path{"/com/ubuntu/connectivity1/modem/%1"};
1726- return path.arg(serial);
1727+ return path.arg(counter++);
1728 }
1729
1730- inline QString simPath(const QString &imsi)
1731+ inline QString simPath()
1732 {
1733+ static int counter {0};
1734 static QString path{"/com/ubuntu/connectivity1/sim/%1"};
1735- return path.arg(imsi);
1736+ return path.arg(counter++);
1737 }
1738
1739
1740
1741=== modified file 'tests/integration/CMakeLists.txt'
1742--- tests/integration/CMakeLists.txt 2015-10-20 10:20:17 +0000
1743+++ tests/integration/CMakeLists.txt 2016-06-22 09:42:47 +0000
1744@@ -13,6 +13,8 @@
1745 test-indicator.cpp
1746 test-indicator-vpn.cpp
1747 test-connectivity-api.cpp
1748+ test-connectivity-api-modem.cpp
1749+ test-connectivity-api-sim.cpp
1750 test-connectivity-api-vpn.cpp
1751 )
1752
1753
1754=== modified file 'tests/integration/indicator-network-test-base.cpp'
1755--- tests/integration/indicator-network-test-base.cpp 2015-11-20 13:14:50 +0000
1756+++ tests/integration/indicator-network-test-base.cpp 2016-06-22 09:42:47 +0000
1757@@ -42,14 +42,16 @@
1758
1759 void IndicatorNetworkTestBase::SetUp()
1760 {
1761+ qputenv("INDICATOR_NETWORK_SETTINGS_PATH", temporaryDir.path().toUtf8().constData());
1762+
1763 if (qEnvironmentVariableIsSet("TEST_WITH_BUSTLE"))
1764 {
1765+ QDir::temp().mkpath("indicator-network-tests");
1766+ QDir testDir(QDir::temp().filePath("indicator-network-tests"));
1767+
1768 const TestInfo* const test_info =
1769 UnitTest::GetInstance()->current_test_info();
1770
1771- QDir::temp().mkpath("indicator-network-tests");
1772- QDir testDir(QDir::temp().filePath("indicator-network-tests"));
1773-
1774 dbusTestRunner.registerService(
1775 DBusServicePtr(
1776 new QProcessDBusService(
1777@@ -67,7 +69,7 @@
1778 dbusMock.registerNetworkManager();
1779 dbusMock.registerNotificationDaemon();
1780 // By default the ofono mock starts with one modem
1781- dbusMock.registerOfono();
1782+ dbusMock.registerOfono({{"no_modem", true}});
1783 dbusMock.registerURfkill();
1784
1785 dbusMock.registerCustomMock(
1786@@ -142,11 +144,8 @@
1787 ""
1788 ).waitForFinished();
1789
1790- // mock service creates ril_0 automatically
1791- // Initial ConnectionManager properties are insane, fix them here
1792- setConnectionManagerProperty(firstModem(), "Bearer", "none");
1793- setConnectionManagerProperty(firstModem(), "Powered", false);
1794- setConnectionManagerProperty(firstModem(), "Attached", false);
1795+
1796+ modem = createModem("ril_0");
1797
1798 // Identify the test when looking at Bustle logs
1799 QDBusConnection systemConnection = dbusTestRunner.systemConnection();
1800@@ -422,6 +421,17 @@
1801 }
1802 }
1803
1804+QVariantMap IndicatorNetworkTestBase::getConnectionManagerProperties(const QString& path)
1805+{
1806+ auto& ofono(dbusMock.ofonoConnectionManagerInterface(path));
1807+ auto reply = ofono.GetProperties();
1808+ reply.waitForFinished();
1809+ if (reply.isError()) {
1810+ EXPECT_FALSE(reply.isError()) << reply.error().message().toStdString();
1811+ }
1812+ return reply;
1813+}
1814+
1815 void IndicatorNetworkTestBase::setNetworkRegistrationProperty(const QString& path, const QString& propertyName, const QVariant& value)
1816 {
1817 auto& ofono(dbusMock.ofonoNetworkRegistrationInterface(path));
1818@@ -483,6 +493,14 @@
1819 .toggled(toggled);
1820 }
1821
1822+mh::MenuItemMatcher IndicatorNetworkTestBase::mobileDataSwitch(bool toggled)
1823+{
1824+ return mh::MenuItemMatcher::checkbox()
1825+ .label("Cellular data")
1826+ .action("indicator.mobiledata.enabled")
1827+ .toggled(toggled);
1828+}
1829+
1830 mh::MenuItemMatcher IndicatorNetworkTestBase::accessPoint(const string& ssid, Secure secure,
1831 ApMode apMode, ConnectionStatus connectionStatus, uchar strength)
1832 {
1833@@ -637,3 +655,16 @@
1834 .themed_icon("icon", {"network-vpn"})
1835 .toggled(connected == ConnectionStatus::connected);
1836 }
1837+
1838+unique_ptr<QSortFilterProxyModel> IndicatorNetworkTestBase::getSortedModems(Connectivity& connectivity)
1839+{
1840+ auto modems = connectivity.modems();
1841+
1842+ auto sortedModems = make_unique<QSortFilterProxyModel>();
1843+ sortedModems->setSortRole(ModemsListModel::RoleIndex);
1844+ sortedModems->sort(0);
1845+
1846+ sortedModems->setSourceModel(modems);
1847+
1848+ return sortedModems;
1849+}
1850
1851=== modified file 'tests/integration/indicator-network-test-base.h'
1852--- tests/integration/indicator-network-test-base.h 2015-11-20 13:14:50 +0000
1853+++ tests/integration/indicator-network-test-base.h 2016-06-22 09:42:47 +0000
1854@@ -19,6 +19,8 @@
1855 #pragma once
1856
1857 #include <connectivityqt/connectivity.h>
1858+#include <connectivityqt/modems-list-model.h>
1859+
1860
1861 #include <dbus-types.h>
1862
1863@@ -77,9 +79,18 @@
1864 {\
1865 while (signalSpy.size() < signalsExpected)\
1866 {\
1867- ASSERT_TRUE(signalSpy.wait());\
1868- }\
1869- ASSERT_EQ(signalsExpected, signalSpy.size());\
1870+ ASSERT_TRUE(signalSpy.wait()) << "Waiting for " << signalsExpected << " signals, got " << signalSpy.size();\
1871+ }\
1872+ ASSERT_EQ(signalsExpected, signalSpy.size()) << "Waiting for " << signalsExpected << " signals, got " << signalSpy.size();\
1873+}
1874+
1875+#define WAIT_FOR_ROW_COUNT(signalSpy, model, expectedRowCount)\
1876+{\
1877+ while (model->rowCount() < expectedRowCount)\
1878+ {\
1879+ ASSERT_TRUE(signalSpy.wait()) << "Waiting for model to have " << expectedRowCount << " rows, got " << model->rowCount();\
1880+ }\
1881+ ASSERT_EQ(expectedRowCount, model->rowCount()) << "Waiting for model to have " << expectedRowCount << " rows, got " << model->rowCount();\
1882 }
1883
1884 #define CHECK_METHOD_CALL(signalSpy, signalIndex, methodName, ...)\
1885@@ -168,6 +179,8 @@
1886
1887 void setConnectionManagerProperty(const QString& path, const QString& propertyName, const QVariant& value);
1888
1889+ QVariantMap getConnectionManagerProperties(const QString& path);
1890+
1891 void setNetworkRegistrationProperty(const QString& path, const QString& propertyName, const QVariant& value);
1892
1893 OrgFreedesktopDBusMockInterface& notificationsMockInterface();
1894@@ -200,6 +213,7 @@
1895 static QString firstModem();
1896
1897 static unity::gmenuharness::MenuItemMatcher flightModeSwitch(bool toggled = false);
1898+ static unity::gmenuharness::MenuItemMatcher mobileDataSwitch(bool toggled = false);
1899
1900 static unity::gmenuharness::MenuItemMatcher accessPoint(const std::string& ssid, Secure secure,
1901 ApMode apMode, ConnectionStatus connectionStatus, uchar strength = 100);
1902@@ -220,9 +234,24 @@
1903
1904 static unity::gmenuharness::MenuItemMatcher vpnConnection(const std::string& name, ConnectionStatus connected = ConnectionStatus::disconnected);
1905
1906+ static connectivityqt::Sim* getModemSim(const QAbstractItemModel& model, int idx)
1907+ {
1908+ auto sim = model.data(model.index(idx,0),
1909+ connectivityqt::ModemsListModel::RoleSim)
1910+ .value<connectivityqt::Sim*>();
1911+ EXPECT_TRUE(sim);
1912+ return sim;
1913+ }
1914+
1915+ static std::unique_ptr<QSortFilterProxyModel> getSortedModems(connectivityqt::Connectivity& connectivity);
1916+
1917 QtDBusTest::DBusTestRunner dbusTestRunner;
1918
1919 QtDBusMock::DBusMock dbusMock;
1920
1921 QtDBusTest::DBusServicePtr indicator;
1922+
1923+ QString modem;
1924+
1925+ QTemporaryDir temporaryDir;
1926 };
1927
1928=== added directory 'tests/integration/qml'
1929=== added file 'tests/integration/test-connectivity-api-modem.cpp'
1930--- tests/integration/test-connectivity-api-modem.cpp 1970-01-01 00:00:00 +0000
1931+++ tests/integration/test-connectivity-api-modem.cpp 2016-06-22 09:42:47 +0000
1932@@ -0,0 +1,322 @@
1933+/*
1934+ * Copyright (C) 2016 Canonical, Ltd.
1935+ *
1936+ * This program is free software: you can redistribute it and/or modify it
1937+ * under the terms of the GNU General Public License version 3, as published
1938+ * by the Free Software Foundation.
1939+ *
1940+ * This program is distributed in the hope that it will be useful, but
1941+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1942+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1943+ * PURPOSE. See the GNU General Public License for more details.
1944+ *
1945+ * You should have received a copy of the GNU General Public License along
1946+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1947+ *
1948+ * Authors:
1949+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
1950+ * Pete Woods <pete.woods@canonical.com>
1951+ */
1952+
1953+#include <connectivityqt/modem.h>
1954+#include <connectivityqt/modems-list-model.h>
1955+#include <indicator-network-test-base.h>
1956+#include <dbus-types.h>
1957+#include <NetworkManagerSettingsInterface.h>
1958+
1959+#include <QDebug>
1960+#include <QTestEventLoop>
1961+
1962+#define DEFINE_MODEL_LISTENERS \
1963+ QSignalSpy rowsAboutToBeRemovedSpy(modems.get(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)));\
1964+ QSignalSpy rowsRemovedSpy(modems.get(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)));\
1965+ QSignalSpy rowsAboutToBeInsertedSpy(modems.get(), SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));\
1966+ QSignalSpy rowsInsertedSpy(modems.get(), SIGNAL(rowsInserted(const QModelIndex &, int, int)));\
1967+ QSignalSpy dataChangedSpy(modems.get(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &)));\
1968+
1969+#define CLEAR_MODEL_LISTENERS \
1970+ rowsAboutToBeRemovedSpy.clear();\
1971+ rowsRemovedSpy.clear();\
1972+ rowsAboutToBeInsertedSpy.clear();\
1973+ rowsInsertedSpy.clear();\
1974+ dataChangedSpy.clear();
1975+
1976+struct SS {
1977+ QString iccid;
1978+ QString imsi;
1979+ QString primaryPhoneNumber;
1980+ bool locked;
1981+ bool present;
1982+ QString mcc;
1983+ QString mnc;
1984+ QList<QString> preferredLanguages;
1985+
1986+ bool operator==(const SS& other) const
1987+ {
1988+ return iccid == other.iccid
1989+ && imsi == other.imsi
1990+ && primaryPhoneNumber == other.primaryPhoneNumber
1991+ && locked == other.locked && present == other.present
1992+ && mcc == other.mcc && mnc == other.mnc
1993+ && preferredLanguages == other.preferredLanguages;
1994+ }
1995+};
1996+typedef QPair<int, SS> MS;
1997+typedef QList<MS> MSL;
1998+
1999+inline void PrintTo (const SS& simState, std::ostream* os)
2000+{
2001+ *os << "SS("
2002+ << "ICCID: " << simState.iccid.toStdString () << ", "
2003+ << "IMSI: " << simState.imsi.toStdString () << ", "
2004+ << "Phone #: " << simState.primaryPhoneNumber.toStdString () << ", "
2005+ << "Locked: " << (simState.locked ? "y" : "n") << ", "
2006+ << "Present: " << (simState.present ? "y" : "n") << ", "
2007+ << "MCC: " << simState.mcc.toStdString () << ", "
2008+ << "MNC: " << simState.mnc.toStdString () << ", "
2009+ << "Langs: " << QStringList(simState.preferredLanguages).join (",").toStdString () << ")";
2010+}
2011+
2012+inline void PrintTo(const MS& modemState, std::ostream* os) {
2013+ *os << "MS(" << modemState.first << ", " ;
2014+ PrintTo(modemState.second, os);
2015+ *os << ")";
2016+}
2017+
2018+using namespace std;
2019+using namespace testing;
2020+using namespace connectivityqt;
2021+
2022+namespace
2023+{
2024+
2025+class TestConnectivityApiModem: public IndicatorNetworkTestBase
2026+{
2027+protected:
2028+ static void SetUpTestCase()
2029+ {
2030+ Connectivity::registerMetaTypes();
2031+ }
2032+
2033+ MSL modemList(QAbstractItemModel& model)
2034+ {
2035+ MSL modemStates;
2036+ int rowCount(model.rowCount());
2037+ for (int i = 0; i < rowCount; ++i)
2038+ {
2039+ auto idx = model.index(i, 0);
2040+ MS modemState;
2041+ modemState.first = model.data(idx, ModemsListModel::Roles::RoleIndex).toInt();
2042+ EXPECT_FALSE(model.data(idx, ModemsListModel::Roles::RoleSerial).toString().isEmpty());
2043+
2044+ SS simState;
2045+ auto sim = qvariant_cast<Sim*>(model.data(idx, ModemsListModel::Roles::RoleSim));
2046+
2047+ if (sim)
2048+ {
2049+ simState.iccid = sim->iccid ();
2050+ simState.imsi = sim->imsi();
2051+ simState.primaryPhoneNumber = sim->primaryPhoneNumber ();
2052+ simState.locked = sim->locked ();
2053+ simState.present = sim->present ();
2054+ simState.mcc = sim->mcc ();
2055+ simState.mnc = sim->mnc ();
2056+ simState.preferredLanguages = sim->preferredLanguages ();
2057+
2058+ modemState.second = simState;
2059+ }
2060+ else
2061+ {
2062+ EXPECT_TRUE(sim) << "Could not get a SIM at index " << i
2063+ << " from ModemModel";
2064+ }
2065+
2066+ modemStates << modemState;
2067+ }
2068+ return modemStates;
2069+ }
2070+};
2071+
2072+TEST_F(TestConnectivityApiModem, SingleModemAtStartup)
2073+{
2074+ // Add a physical device to use for the connection
2075+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2076+ createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2077+
2078+ // Start the indicator
2079+ ASSERT_NO_THROW(startIndicator());
2080+
2081+ // Connect the the service
2082+ auto connectivity(newConnectivity());
2083+
2084+ // Get the modems model
2085+ auto modems = getSortedModems(*connectivity);
2086+
2087+ DEFINE_MODEL_LISTENERS
2088+
2089+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, modems, 1)
2090+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2091+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2092+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2093+
2094+ EXPECT_EQ(MSL({
2095+ MS{1, SS{
2096+ "893581234000000000000",
2097+ "310150000000000",
2098+ "123456789",
2099+ false,
2100+ true,
2101+ "310",
2102+ "150",
2103+ {"en"}
2104+ }}
2105+ }), modemList(*modems));
2106+}
2107+
2108+TEST_F(TestConnectivityApiModem, TwoModemsAtStartup)
2109+{
2110+ createModem("ril_1");
2111+
2112+ // Add a physical device to use for the connection
2113+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2114+ createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2115+
2116+ // Start the indicator
2117+ ASSERT_NO_THROW(startIndicator());
2118+
2119+ // Connect the the service
2120+ auto connectivity(newConnectivity());
2121+
2122+ // Get the modems model
2123+ auto modems = getSortedModems(*connectivity);
2124+
2125+ DEFINE_MODEL_LISTENERS
2126+
2127+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, modems, 2)
2128+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2129+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2130+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2131+
2132+ EXPECT_EQ(MSL({
2133+ MS{1, SS{
2134+ "893581234000000000000",
2135+ "310150000000000",
2136+ "123456789",
2137+ false,
2138+ true,
2139+ "310",
2140+ "150",
2141+ {"en"}
2142+ }},
2143+ MS{2, SS{
2144+ "893581234000000000001",
2145+ "310150000000001",
2146+ "123456789",
2147+ false,
2148+ true,
2149+ "310",
2150+ "150",
2151+ {"en"}
2152+ }}
2153+ }), modemList(*modems));
2154+}
2155+
2156+TEST_F(TestConnectivityApiModem, AddAModem)
2157+{
2158+ // Add a physical device to use for the connection
2159+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2160+ createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2161+
2162+ // Start the indicator
2163+ ASSERT_NO_THROW(startIndicator());
2164+
2165+ // Connect the the service
2166+ auto connectivity(newConnectivity());
2167+
2168+ // Get the modems model
2169+ auto modems = getSortedModems(*connectivity);
2170+
2171+ DEFINE_MODEL_LISTENERS
2172+
2173+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, modems, 1)
2174+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2175+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2176+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2177+
2178+ EXPECT_EQ(MSL({
2179+ MS{1, SS{
2180+ "893581234000000000000",
2181+ "310150000000000",
2182+ "123456789",
2183+ false,
2184+ true,
2185+ "310",
2186+ "150",
2187+ {"en"}
2188+ }}
2189+ }), modemList(*modems));
2190+
2191+ CLEAR_MODEL_LISTENERS
2192+
2193+ createModem("ril_1");
2194+
2195+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, modems, 2)
2196+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2197+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2198+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2199+
2200+ EXPECT_EQ(MSL({
2201+ MS{1, SS{
2202+ "893581234000000000000",
2203+ "310150000000000",
2204+ "123456789",
2205+ false,
2206+ true,
2207+ "310",
2208+ "150",
2209+ {"en"}
2210+ }},
2211+ MS{2, SS{
2212+ "893581234000000000001",
2213+ "310150000000001",
2214+ "123456789",
2215+ false,
2216+ true,
2217+ "310",
2218+ "150",
2219+ {"en"}
2220+ }}
2221+ }), modemList(*modems));
2222+
2223+ CLEAR_MODEL_LISTENERS
2224+}
2225+
2226+TEST_F(TestConnectivityApiModem, ModemProperties)
2227+{
2228+ // Add a physical device to use for the connection
2229+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2230+ createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2231+
2232+ // Start the indicator
2233+ ASSERT_NO_THROW(startIndicator());
2234+
2235+ // Connect the the service
2236+ auto connectivity(newConnectivity());
2237+
2238+ // Get the modems model
2239+ auto modems = getSortedModems(*connectivity);
2240+
2241+ DEFINE_MODEL_LISTENERS
2242+
2243+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, modems, 1)
2244+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2245+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2246+
2247+ auto modem = qvariant_cast<Modem*>(modems->data(modems->index(0, 0), ModemsListModel::Roles::RoleModem));
2248+
2249+ EXPECT_EQ(1, modem->index());
2250+ EXPECT_EQ("12345678-1234-1234-1234-000000000000", modem->serial().toStdString());
2251+ EXPECT_TRUE(modem->sim());
2252+}
2253+
2254+}
2255
2256=== added file 'tests/integration/test-connectivity-api-sim.cpp'
2257--- tests/integration/test-connectivity-api-sim.cpp 1970-01-01 00:00:00 +0000
2258+++ tests/integration/test-connectivity-api-sim.cpp 2016-06-22 09:42:47 +0000
2259@@ -0,0 +1,375 @@
2260+/*
2261+ * Copyright (C) 2016 Canonical, Ltd.
2262+ *
2263+ * This program is free software: you can redistribute it and/or modify it
2264+ * under the terms of the GNU General Public License version 3, as published
2265+ * by the Free Software Foundation.
2266+ *
2267+ * This program is distributed in the hope that it will be useful, but
2268+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2269+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2270+ * PURPOSE. See the GNU General Public License for more details.
2271+ *
2272+ * You should have received a copy of the GNU General Public License along
2273+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2274+ *
2275+ * Authors:
2276+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
2277+ * Pete Woods <pete.woods@canonical.com>
2278+ */
2279+
2280+#include <connectivityqt/sim.h>
2281+#include <connectivityqt/sims-list-model.h>
2282+#include <indicator-network-test-base.h>
2283+#include <dbus-types.h>
2284+#include <NetworkManagerSettingsInterface.h>
2285+
2286+#include <QDebug>
2287+#include <QTestEventLoop>
2288+
2289+#define DEFINE_MODEL_LISTENERS \
2290+ QSignalSpy rowsAboutToBeRemovedSpy(sims.get(), SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)));\
2291+ QSignalSpy rowsRemovedSpy(sims.get(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)));\
2292+ QSignalSpy rowsAboutToBeInsertedSpy(sims.get(), SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));\
2293+ QSignalSpy rowsInsertedSpy(sims.get(), SIGNAL(rowsInserted(const QModelIndex &, int, int)));\
2294+ QSignalSpy dataChangedSpy(sims.get(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &)));\
2295+
2296+#define CLEAR_MODEL_LISTENERS \
2297+ rowsAboutToBeRemovedSpy.clear();\
2298+ rowsRemovedSpy.clear();\
2299+ rowsAboutToBeInsertedSpy.clear();\
2300+ rowsInsertedSpy.clear();\
2301+ dataChangedSpy.clear();
2302+
2303+struct SS {
2304+ QString iccid;
2305+ QString imsi;
2306+ QString primaryPhoneNumber;
2307+ bool locked;
2308+ bool present;
2309+ QString mcc;
2310+ QString mnc;
2311+ QList<QString> preferredLanguages;
2312+ bool dataRoamingEnabled;
2313+
2314+ bool operator==(const SS& other) const
2315+ {
2316+ return iccid == other.iccid
2317+ && imsi == other.imsi
2318+ && primaryPhoneNumber == other.primaryPhoneNumber
2319+ && locked == other.locked && present == other.present
2320+ && mcc == other.mcc && mnc == other.mnc
2321+ && preferredLanguages == other.preferredLanguages
2322+ && dataRoamingEnabled == other.dataRoamingEnabled;
2323+ }
2324+};
2325+typedef QList<SS> SSL;
2326+
2327+inline void PrintTo (const SS& simState, std::ostream* os)
2328+{
2329+ *os << "SS("
2330+ << "ICCID: " << simState.iccid.toStdString () << ", "
2331+ << "IMSI: " << simState.imsi.toStdString () << ", "
2332+ << "Phone #: " << simState.primaryPhoneNumber.toStdString () << ", "
2333+ << "Locked: " << (simState.locked ? "y" : "n") << ", "
2334+ << "Present: " << (simState.present ? "y" : "n") << ", "
2335+ << "MCC: " << simState.mcc.toStdString () << ", "
2336+ << "MNC: " << simState.mnc.toStdString () << ", "
2337+ << "Langs: " << QStringList(simState.preferredLanguages).join (",").toStdString ()
2338+ << "Roaming: " << (simState.dataRoamingEnabled ? "y" : "n")
2339+ << ")";
2340+}
2341+
2342+using namespace std;
2343+using namespace testing;
2344+using namespace connectivityqt;
2345+
2346+namespace
2347+{
2348+
2349+class TestConnectivityApiSim: public IndicatorNetworkTestBase
2350+{
2351+protected:
2352+ static void SetUpTestCase()
2353+ {
2354+ Connectivity::registerMetaTypes();
2355+ }
2356+
2357+ unique_ptr<QSortFilterProxyModel> getSortedSims(Connectivity& connectivity)
2358+ {
2359+ auto sims = connectivity.sims();
2360+
2361+ auto sortedSims = make_unique<QSortFilterProxyModel>();
2362+ sortedSims->setSortRole(SimsListModel::RoleIccid);
2363+ sortedSims->sort(0);
2364+
2365+ sortedSims->setSourceModel(sims);
2366+
2367+ return sortedSims;
2368+ }
2369+
2370+ connectivityqt::Sim* getSim(const QAbstractItemModel& model, int idx)
2371+ {
2372+ auto sim = model.data(model.index(idx,0),
2373+ connectivityqt::SimsListModel::RoleSim)
2374+ .value<connectivityqt::Sim*>();
2375+ EXPECT_TRUE(sim);
2376+ return sim;
2377+ }
2378+
2379+ SSL simList(QAbstractItemModel& model)
2380+ {
2381+ SSL simStates;
2382+ int rowCount(model.rowCount());
2383+ for (int i = 0; i < rowCount; ++i)
2384+ {
2385+ auto idx = model.index(i, 0);
2386+
2387+ SS simState;
2388+ simState.iccid = model.data(idx, SimsListModel::RoleIccid).toString();
2389+ simState.imsi = model.data(idx, SimsListModel::RoleImsi).toString();
2390+ simState.primaryPhoneNumber = model.data(idx, SimsListModel::RolePrimaryPhoneNumber).toString();
2391+ simState.locked = model.data(idx, SimsListModel::RoleLocked).toBool();
2392+ simState.present = model.data(idx, SimsListModel::RolePresent).toBool();
2393+ simState.mcc = model.data(idx, SimsListModel::RoleMcc).toString();
2394+ simState.mnc = model.data(idx, SimsListModel::RoleMnc).toString();
2395+ simState.preferredLanguages = model.data(idx, SimsListModel::RolePreferredLanguages).toStringList();
2396+ simState.dataRoamingEnabled = model.data(idx, SimsListModel::RoleDataRoamingEnabled).toBool();
2397+
2398+ simStates << simState;
2399+ }
2400+ return simStates;
2401+ }
2402+};
2403+
2404+TEST_F(TestConnectivityApiSim, SingleSimAtStartup)
2405+{
2406+ // Add a physical device to use for the connection
2407+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2408+ auto device = createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2409+
2410+ // Start the indicator
2411+ ASSERT_NO_THROW(startIndicator());
2412+
2413+ // Connect the the service
2414+ auto connectivity(newConnectivity());
2415+
2416+ // Get the SIMs model
2417+ auto sims = getSortedSims(*connectivity);
2418+
2419+ DEFINE_MODEL_LISTENERS
2420+
2421+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, sims, 1)
2422+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2423+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2424+
2425+ auto sim = getSim(*sims, 0);
2426+ while (sim->imsi().isEmpty() || sim->primaryPhoneNumber().isEmpty())
2427+ {
2428+ EXPECT_TRUE(dataChangedSpy.wait());
2429+ }
2430+
2431+ EXPECT_EQ(SSL({
2432+ SS{
2433+ "893581234000000000000",
2434+ "310150000000000",
2435+ "123456789",
2436+ false,
2437+ true,
2438+ "310",
2439+ "150",
2440+ {"en"},
2441+ false
2442+ }
2443+ }), simList(*sims));
2444+}
2445+
2446+TEST_F(TestConnectivityApiSim, TwoSimsAtStartup)
2447+{
2448+ createModem("ril_1");
2449+
2450+ // Add a physical device to use for the connection
2451+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2452+ auto device = createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2453+
2454+ // Start the indicator
2455+ ASSERT_NO_THROW(startIndicator());
2456+
2457+ // Connect the the service
2458+ auto connectivity(newConnectivity());
2459+
2460+ // Get the SIMs model
2461+ auto sims = getSortedSims(*connectivity);
2462+
2463+ DEFINE_MODEL_LISTENERS
2464+
2465+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, sims, 2)
2466+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2467+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2468+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2469+
2470+ auto sim = getSim(*sims, 0);
2471+ while (sim->imsi().isEmpty() || sim->primaryPhoneNumber().isEmpty())
2472+ {
2473+ EXPECT_TRUE(dataChangedSpy.wait());
2474+ }
2475+ auto sim2 = getSim(*sims, 1);
2476+ while (sim2->imsi().isEmpty() || sim2->primaryPhoneNumber().isEmpty())
2477+ {
2478+ EXPECT_TRUE(dataChangedSpy.wait());
2479+ }
2480+
2481+ EXPECT_EQ(SSL({
2482+ SS{
2483+ "893581234000000000000",
2484+ "310150000000000",
2485+ "123456789",
2486+ false,
2487+ true,
2488+ "310",
2489+ "150",
2490+ {"en"},
2491+ false
2492+ },
2493+ SS{
2494+ "893581234000000000001",
2495+ "310150000000001",
2496+ "123456789",
2497+ false,
2498+ true,
2499+ "310",
2500+ "150",
2501+ {"en"},
2502+ false
2503+ }
2504+ }), simList(*sims));
2505+}
2506+
2507+TEST_F(TestConnectivityApiSim, AddASim)
2508+{
2509+ // Add a physical device to use for the connection
2510+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2511+ auto device = createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2512+
2513+ // Start the indicator
2514+ ASSERT_NO_THROW(startIndicator());
2515+
2516+ // Connect the the service
2517+ auto connectivity(newConnectivity());
2518+
2519+ // Get the SIMs model
2520+ auto sims = getSortedSims(*connectivity);
2521+
2522+ DEFINE_MODEL_LISTENERS
2523+
2524+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, sims, 1)
2525+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2526+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2527+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2528+
2529+ auto sim = getSim(*sims, 0);
2530+ while (sim->imsi().isEmpty() || sim->primaryPhoneNumber().isEmpty())
2531+ {
2532+ EXPECT_TRUE(dataChangedSpy.wait());
2533+ }
2534+
2535+ EXPECT_EQ(SSL({
2536+ SS{
2537+ "893581234000000000000",
2538+ "310150000000000",
2539+ "123456789",
2540+ false,
2541+ true,
2542+ "310",
2543+ "150",
2544+ {"en"},
2545+ false
2546+ }
2547+ }), simList(*sims));
2548+
2549+ CLEAR_MODEL_LISTENERS
2550+
2551+ createModem("ril_1");
2552+
2553+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, sims, 2)
2554+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2555+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2556+
2557+ auto sim2 = getSim(*sims, 1);
2558+ while (sim2->imsi().isEmpty() || sim2->primaryPhoneNumber().isEmpty())
2559+ {
2560+ EXPECT_TRUE(dataChangedSpy.wait());
2561+ }
2562+
2563+ EXPECT_EQ(SSL({
2564+ SS{
2565+ "893581234000000000000",
2566+ "310150000000000",
2567+ "123456789",
2568+ false,
2569+ true,
2570+ "310",
2571+ "150",
2572+ {"en"},
2573+ false
2574+ },
2575+ SS{
2576+ "893581234000000000001",
2577+ "310150000000001",
2578+ "123456789",
2579+ false,
2580+ true,
2581+ "310",
2582+ "150",
2583+ {"en"},
2584+ false
2585+ }
2586+ }), simList(*sims));
2587+}
2588+
2589+TEST_F(TestConnectivityApiSim, SimProperties)
2590+{
2591+ // Add a physical device to use for the connection
2592+ setGlobalConnectedState(NM_STATE_CONNECTED_GLOBAL);
2593+ auto device = createWiFiDevice(NM_DEVICE_STATE_ACTIVATED);
2594+
2595+ // Start the indicator
2596+ ASSERT_NO_THROW(startIndicator());
2597+
2598+ // Connect the the service
2599+ auto connectivity(newConnectivity());
2600+
2601+ // Get the SIMs model
2602+ auto sims = getSortedSims(*connectivity);
2603+
2604+ DEFINE_MODEL_LISTENERS
2605+
2606+ WAIT_FOR_ROW_COUNT(rowsInsertedSpy, sims, 1)
2607+ EXPECT_TRUE(rowsAboutToBeRemovedSpy.isEmpty ());
2608+ EXPECT_TRUE(rowsRemovedSpy.isEmpty ());
2609+ EXPECT_TRUE(dataChangedSpy.isEmpty ());
2610+
2611+ auto sim = qvariant_cast<Sim*>(sims->data(sims->index(0, 0), SimsListModel::Roles::RoleSim));
2612+ ASSERT_TRUE(sim);
2613+ while (sim->imsi().isEmpty() || sim->primaryPhoneNumber().isEmpty())
2614+ {
2615+ EXPECT_TRUE(dataChangedSpy.wait());
2616+ }
2617+
2618+ EXPECT_EQ("893581234000000000000", sim->iccid().toStdString());
2619+ EXPECT_EQ("310150000000000", sim->imsi().toStdString());
2620+ EXPECT_EQ("123456789", sim->primaryPhoneNumber().toStdString());
2621+ EXPECT_FALSE(sim->locked());
2622+ EXPECT_TRUE(sim->present());
2623+ EXPECT_EQ("310", sim->mcc().toStdString());
2624+ EXPECT_EQ("150", sim->mnc().toStdString());
2625+ EXPECT_EQ(QStringList{"en"}, sim->preferredLanguages());
2626+}
2627+
2628+TEST_F(TestConnectivityApiSim, RoamingAllowed)
2629+{
2630+// test that roaming allowed has an effect.
2631+}
2632+
2633+
2634+}
2635
2636=== modified file 'tests/integration/test-connectivity-api.cpp'
2637--- tests/integration/test-connectivity-api.cpp 2016-01-14 13:38:38 +0000
2638+++ tests/integration/test-connectivity-api.cpp 2016-06-22 09:42:47 +0000
2639@@ -764,4 +764,128 @@
2640
2641 EXPECT_TRUE(connectivity->modemAvailable());
2642 }
2643+
2644+TEST_F(TestConnectivityApi, MobileDataDisablePowersOffAllSims)
2645+{
2646+ auto modem2 = createModem("ril_1");
2647+ setConnectionManagerProperty(modem2, "Powered", true);
2648+
2649+ setGlobalConnectedState(NM_STATE_DISCONNECTED);
2650+ auto device = createWiFiDevice(NM_DEVICE_STATE_DISCONNECTED);
2651+
2652+ // Start the indicator
2653+ ASSERT_NO_THROW(startIndicator());
2654+
2655+ // Connect the the service
2656+ auto connectivity(newConnectivity());
2657+
2658+ QSignalSpy mobileDataEnabledSpy(connectivity.get(), SIGNAL(mobileDataEnabledUpdated(bool)));
2659+ QSignalSpy simForMobileDataSpy(connectivity.get(), SIGNAL(simForMobileDataUpdated(Sim*)));
2660+
2661+ // One of the modems was started and we had no settings.
2662+ // So we start by assuming mobile data was enabled.
2663+ if (!connectivity->mobileDataEnabled())
2664+ {
2665+ WAIT_FOR_SIGNALS(mobileDataEnabledSpy, 1)
2666+ }
2667+ mobileDataEnabledSpy.clear();
2668+ EXPECT_TRUE(connectivity->mobileDataEnabled());
2669+
2670+ if (!connectivity->simForMobileData())
2671+ {
2672+ WAIT_FOR_SIGNALS(simForMobileDataSpy, 1)
2673+ }
2674+ simForMobileDataSpy.clear();
2675+ EXPECT_TRUE(connectivity->simForMobileData() != nullptr);
2676+
2677+
2678+ QSignalSpy simsModelRowsInsertedSpy(connectivity->sims(), SIGNAL(rowsInserted(const QModelIndex &, int, int)));
2679+ QSignalSpy modemsModelRowsInsertedSpy(connectivity->modems(), SIGNAL(rowsInserted(const QModelIndex &, int, int)));
2680+ WAIT_FOR_ROW_COUNT(simsModelRowsInsertedSpy, connectivity->sims(), 2)
2681+ WAIT_FOR_ROW_COUNT(modemsModelRowsInsertedSpy, connectivity->modems(), 2)
2682+
2683+ auto modems = getSortedModems(*connectivity);
2684+ auto simForMobileData = connectivity->simForMobileData();
2685+ auto secondSim = getModemSim(*modems, 1);
2686+
2687+ ASSERT_TRUE(simForMobileData);
2688+ ASSERT_TRUE(secondSim);
2689+ // These should be the exact same object.
2690+ EXPECT_TRUE(simForMobileData == secondSim);
2691+
2692+ // Only the second modem should be powered
2693+ EXPECT_FALSE(getConnectionManagerProperties(modem)["Powered"].toBool());
2694+ EXPECT_TRUE(getConnectionManagerProperties(modem2)["Powered"].toBool());
2695+
2696+ auto& connectionManager(dbusMock.ofonoConnectionManagerInterface(modem2));
2697+ QSignalSpy connectionManagerPropertyChangedSpy(
2698+ &connectionManager,
2699+ SIGNAL(PropertyChanged(const QString &, const QDBusVariant &)));
2700+
2701+ // Disable all mobile data.
2702+ connectivity->setMobileDataEnabled(false);
2703+
2704+ WAIT_FOR_SIGNALS(connectionManagerPropertyChangedSpy, 1)
2705+
2706+ // Both modems should by un-powered
2707+ EXPECT_FALSE(getConnectionManagerProperties(modem)["Powered"].toBool());
2708+ EXPECT_FALSE(getConnectionManagerProperties(modem2)["Powered"].toBool());
2709+
2710+ if (connectivity->mobileDataEnabled())
2711+ {
2712+ WAIT_FOR_SIGNALS(mobileDataEnabledSpy, 1)
2713+ }
2714+ EXPECT_FALSE(connectivity->mobileDataEnabled());
2715+}
2716+
2717+TEST_F(TestConnectivityApi, SettingsRestoredOnStartup)
2718+{
2719+
2720+ QString path = temporaryDir.path() + "/config.ini";
2721+ auto settings = make_unique<QSettings>(path, QSettings::IniFormat);
2722+
2723+ settings->beginGroup("Sims/893581234000000000000/");
2724+ settings->setValue("Imsi", "310150000000000");
2725+ settings->setValue("PrimaryPhoneNumber", "123456789");
2726+ settings->setValue("Mcc", "310");
2727+ settings->setValue("Mnc", "150");
2728+ settings->setValue("PreferredLanguages", QVariant(QList<QString>({"en"})));
2729+ settings->setValue("DataRoamingEnabled", true);
2730+ settings->endGroup();
2731+
2732+ settings->beginGroup("Sims/893581234000000000001/");
2733+ settings->setValue("Imsi", "310150000000001");
2734+ settings->setValue("PrimaryPhoneNumber", "123456789");
2735+ settings->setValue("Mcc", "310");
2736+ settings->setValue("Mnc", "150");
2737+ settings->setValue("PreferredLanguages", QVariant(QList<QString>({"en"})));
2738+ settings->setValue("DataRoamingEnabled", false);
2739+ settings->endGroup();
2740+
2741+ settings->setValue("KnownSims", QVariant(QList<QString>({"893581234000000000000", "893581234000000000001"})));
2742+ settings->setValue("SimForMobileData", "893581234000000000001");
2743+ settings->setValue("MobileDataEnabled", true);
2744+ settings->sync();
2745+
2746+ setConnectionManagerProperty(modem, "Powered", true);
2747+ setConnectionManagerProperty(modem, "RoamingAllowed", false);
2748+
2749+ auto modem2 = createModem("ril_1");
2750+ setConnectionManagerProperty(modem2, "Powered", false);
2751+ setConnectionManagerProperty(modem2, "RoamingAllowed", true);
2752+
2753+
2754+ // Start the indicator
2755+ ASSERT_NO_THROW(startIndicator());
2756+
2757+
2758+ // Check that settings are restored on startup
2759+
2760+ EXPECT_FALSE(getConnectionManagerProperties(modem)["Powered"].toBool());
2761+ EXPECT_TRUE(getConnectionManagerProperties(modem)["RoamingAllowed"].toBool());
2762+
2763+ EXPECT_TRUE(getConnectionManagerProperties(modem2)["Powered"].toBool());
2764+ EXPECT_FALSE(getConnectionManagerProperties(modem2)["RoamingAllowed"].toBool());
2765+}
2766+
2767 }
2768
2769=== modified file 'tests/integration/test-indicator.cpp'
2770--- tests/integration/test-indicator.cpp 2015-11-20 10:25:10 +0000
2771+++ tests/integration/test-indicator.cpp 2016-06-22 09:42:47 +0000
2772@@ -24,6 +24,7 @@
2773
2774 using namespace std;
2775 using namespace testing;
2776+using namespace connectivityqt;
2777 namespace mh = unity::gmenuharness;
2778
2779 namespace
2780@@ -44,9 +45,10 @@
2781 .state_icons({"gsm-3g-full", "nm-no-connection"})
2782 .mode(mh::MenuItemMatcher::Mode::all)
2783 .submenu()
2784- .item(flightModeSwitch())
2785+ .item(flightModeSwitch())
2786 .item(mh::MenuItemMatcher()
2787 .section()
2788+ .item(mobileDataSwitch(false))
2789 .item(modemInfo("", "fake.tel", "gsm-3g-full"))
2790 .item(cellularSettings())
2791 )
2792@@ -195,6 +197,7 @@
2793 .item(flightModeSwitch())
2794 .item(mh::MenuItemMatcher()
2795 .section()
2796+ .item(mobileDataSwitch())
2797 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2798 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-full"))
2799 .item(cellularSettings())
2800@@ -285,6 +288,8 @@
2801 .mode(mh::MenuItemMatcher::Mode::starts_with)
2802 .item(flightModeSwitch())
2803 .item(mh::MenuItemMatcher()
2804+ .section()
2805+ .item(mobileDataSwitch(false))
2806 .item(modemInfo("", "No SIM", "no-simcard"))
2807 .item(cellularSettings())
2808 )
2809@@ -311,6 +316,8 @@
2810 .mode(mh::MenuItemMatcher::Mode::starts_with)
2811 .item(flightModeSwitch())
2812 .item(mh::MenuItemMatcher()
2813+ .section()
2814+ .item(mobileDataSwitch(false))
2815 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2816 .item(modemInfo("SIM 2", "No SIM", "no-simcard"))
2817 .item(cellularSettings())
2818@@ -338,6 +345,8 @@
2819 .mode(mh::MenuItemMatcher::Mode::starts_with)
2820 .item(flightModeSwitch())
2821 .item(mh::MenuItemMatcher()
2822+ .section()
2823+ .item(mobileDataSwitch(false))
2824 .item(modemInfo("", "SIM Locked", "simcard-locked", true)
2825 .string_attribute("x-canonical-modem-locked-action", "indicator.modem.1::locked")
2826 )
2827@@ -356,6 +365,8 @@
2828 .mode(mh::MenuItemMatcher::Mode::starts_with)
2829 .item(flightModeSwitch())
2830 .item(mh::MenuItemMatcher()
2831+ .section()
2832+ .item(mobileDataSwitch())
2833 .item(modemInfo("", "fake.tel", "gsm-3g-full"))
2834 .item(cellularSettings())
2835 )
2836@@ -383,6 +394,8 @@
2837 .mode(mh::MenuItemMatcher::Mode::starts_with)
2838 .item(flightModeSwitch())
2839 .item(mh::MenuItemMatcher()
2840+ .section()
2841+ .item(mobileDataSwitch())
2842 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2843 .item(modemInfo("SIM 2", "SIM Locked", "simcard-locked", true))
2844 .item(cellularSettings())
2845@@ -400,6 +413,8 @@
2846 .mode(mh::MenuItemMatcher::Mode::starts_with)
2847 .item(flightModeSwitch())
2848 .item(mh::MenuItemMatcher()
2849+ .section()
2850+ .item(mobileDataSwitch())
2851 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2852 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-full"))
2853 .item(cellularSettings())
2854@@ -426,6 +441,8 @@
2855 .mode(mh::MenuItemMatcher::Mode::starts_with)
2856 .item(flightModeSwitch())
2857 .item(mh::MenuItemMatcher()
2858+ .section()
2859+ .item(mobileDataSwitch())
2860 .item(modemInfo("", "No Signal", "gsm-3g-no-service"))
2861 .item(cellularSettings())
2862 )
2863@@ -442,6 +459,8 @@
2864 .mode(mh::MenuItemMatcher::Mode::starts_with)
2865 .item(flightModeSwitch())
2866 .item(mh::MenuItemMatcher()
2867+ .section()
2868+ .item(mobileDataSwitch())
2869 .item(modemInfo("", "Searching", "gsm-3g-disabled"))
2870 .item(cellularSettings())
2871 )
2872@@ -461,6 +480,8 @@
2873 .mode(mh::MenuItemMatcher::Mode::starts_with)
2874 .item(flightModeSwitch())
2875 .item(mh::MenuItemMatcher()
2876+ .section()
2877+ .item(mobileDataSwitch())
2878 .item(modemInfo("", "fake.tel", "gsm-3g-none"))
2879 .item(cellularSettings())
2880 )
2881@@ -477,6 +498,8 @@
2882 .mode(mh::MenuItemMatcher::Mode::starts_with)
2883 .item(flightModeSwitch())
2884 .item(mh::MenuItemMatcher()
2885+ .section()
2886+ .item(mobileDataSwitch())
2887 .item(modemInfo("", "fake.tel", "gsm-3g-low"))
2888 .item(cellularSettings())
2889 )
2890@@ -493,6 +516,8 @@
2891 .mode(mh::MenuItemMatcher::Mode::starts_with)
2892 .item(flightModeSwitch())
2893 .item(mh::MenuItemMatcher()
2894+ .section()
2895+ .item(mobileDataSwitch())
2896 .item(modemInfo("", "fake.tel", "gsm-3g-medium"))
2897 .item(cellularSettings())
2898 )
2899@@ -509,6 +534,8 @@
2900 .mode(mh::MenuItemMatcher::Mode::starts_with)
2901 .item(flightModeSwitch())
2902 .item(mh::MenuItemMatcher()
2903+ .section()
2904+ .item(mobileDataSwitch())
2905 .item(modemInfo("", "fake.tel", "gsm-3g-high"))
2906 .item(cellularSettings())
2907 )
2908@@ -525,6 +552,8 @@
2909 .mode(mh::MenuItemMatcher::Mode::starts_with)
2910 .item(flightModeSwitch())
2911 .item(mh::MenuItemMatcher()
2912+ .section()
2913+ .item(mobileDataSwitch())
2914 .item(modemInfo("", "fake.tel", "gsm-3g-full"))
2915 .item(cellularSettings())
2916 )
2917@@ -551,6 +580,8 @@
2918 .mode(mh::MenuItemMatcher::Mode::starts_with)
2919 .item(flightModeSwitch())
2920 .item(mh::MenuItemMatcher()
2921+ .section()
2922+ .item(mobileDataSwitch())
2923 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2924 .item(modemInfo("SIM 2", "No Signal", "gsm-3g-no-service"))
2925 .item(cellularSettings())
2926@@ -568,6 +599,8 @@
2927 .mode(mh::MenuItemMatcher::Mode::starts_with)
2928 .item(flightModeSwitch())
2929 .item(mh::MenuItemMatcher()
2930+ .section()
2931+ .item(mobileDataSwitch())
2932 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2933 .item(modemInfo("SIM 2", "Searching", "gsm-3g-disabled"))
2934 .item(cellularSettings())
2935@@ -588,6 +621,8 @@
2936 .mode(mh::MenuItemMatcher::Mode::starts_with)
2937 .item(flightModeSwitch())
2938 .item(mh::MenuItemMatcher()
2939+ .section()
2940+ .item(mobileDataSwitch())
2941 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2942 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-none"))
2943 .item(cellularSettings())
2944@@ -605,6 +640,8 @@
2945 .mode(mh::MenuItemMatcher::Mode::starts_with)
2946 .item(flightModeSwitch())
2947 .item(mh::MenuItemMatcher()
2948+ .section()
2949+ .item(mobileDataSwitch())
2950 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2951 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-low"))
2952 .item(cellularSettings())
2953@@ -622,6 +659,8 @@
2954 .mode(mh::MenuItemMatcher::Mode::starts_with)
2955 .item(flightModeSwitch())
2956 .item(mh::MenuItemMatcher()
2957+ .section()
2958+ .item(mobileDataSwitch())
2959 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2960 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-medium"))
2961 .item(cellularSettings())
2962@@ -639,6 +678,8 @@
2963 .mode(mh::MenuItemMatcher::Mode::starts_with)
2964 .item(flightModeSwitch())
2965 .item(mh::MenuItemMatcher()
2966+ .section()
2967+ .item(mobileDataSwitch())
2968 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2969 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-high"))
2970 .item(cellularSettings())
2971@@ -656,6 +697,8 @@
2972 .mode(mh::MenuItemMatcher::Mode::starts_with)
2973 .item(flightModeSwitch())
2974 .item(mh::MenuItemMatcher()
2975+ .section()
2976+ .item(mobileDataSwitch())
2977 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
2978 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-full"))
2979 .item(cellularSettings())
2980@@ -688,6 +731,8 @@
2981 .mode(mh::MenuItemMatcher::Mode::starts_with)
2982 .item(flightModeSwitch(false))
2983 .item(mh::MenuItemMatcher()
2984+ .section()
2985+ .item(mobileDataSwitch())
2986 .item(modemInfo("", "No SIM", "no-simcard"))
2987 .item(cellularSettings())
2988 )
2989@@ -728,6 +773,8 @@
2990 .mode(mh::MenuItemMatcher::Mode::starts_with)
2991 .item(flightModeSwitch(true))
2992 .item(mh::MenuItemMatcher()
2993+ .section()
2994+ .item(mobileDataSwitch())
2995 .item(modemInfo("", "No SIM", "no-simcard"))
2996 .item(cellularSettings())
2997 )
2998@@ -761,6 +808,8 @@
2999 .mode(mh::MenuItemMatcher::Mode::starts_with)
3000 .item(flightModeSwitch(false))
3001 .item(mh::MenuItemMatcher()
3002+ .section()
3003+ .item(mobileDataSwitch())
3004 .item(modemInfo("", "No SIM", "no-simcard"))
3005 .item(cellularSettings())
3006 )
3007@@ -793,6 +842,8 @@
3008 .mode(mh::MenuItemMatcher::Mode::starts_with)
3009 .item(flightModeSwitch(false))
3010 .item(mh::MenuItemMatcher()
3011+ .section()
3012+ .item(mobileDataSwitch())
3013 .item(modemInfo("", "SIM Locked", "simcard-locked", true))
3014 .item(cellularSettings())
3015 )
3016@@ -832,6 +883,8 @@
3017 .mode(mh::MenuItemMatcher::Mode::starts_with)
3018 .item(flightModeSwitch(true))
3019 .item(mh::MenuItemMatcher()
3020+ .section()
3021+ .item(mobileDataSwitch())
3022 .item(modemInfo("", "SIM Locked", "simcard-locked", true))
3023 .item(cellularSettings())
3024 )
3025@@ -865,6 +918,8 @@
3026 .mode(mh::MenuItemMatcher::Mode::starts_with)
3027 .item(flightModeSwitch(false))
3028 .item(mh::MenuItemMatcher()
3029+ .section()
3030+ .item(mobileDataSwitch())
3031 .item(modemInfo("", "SIM Locked", "simcard-locked", true))
3032 .item(cellularSettings())
3033 )
3034@@ -908,6 +963,8 @@
3035 .mode(mh::MenuItemMatcher::Mode::starts_with)
3036 .item(flightModeSwitch(false))
3037 .item(mh::MenuItemMatcher()
3038+ .section()
3039+ .item(mobileDataSwitch(false))
3040 .item(modemInfo("", "fake.tel", "gsm-3g-high"))
3041 .item(cellularSettings())
3042 )
3043@@ -959,6 +1016,8 @@
3044 .mode(mh::MenuItemMatcher::Mode::starts_with)
3045 .item(flightModeSwitch(false))
3046 .item(mh::MenuItemMatcher()
3047+ .section()
3048+ .item(mobileDataSwitch(false))
3049 .item(modemInfo("", "fake.tel", "gsm-3g-high"))
3050 .item(cellularSettings())
3051 )
3052@@ -988,6 +1047,8 @@
3053 .mode(mh::MenuItemMatcher::Mode::starts_with)
3054 .item(flightModeSwitch(true))
3055 .item(mh::MenuItemMatcher()
3056+ .section()
3057+ .item(mobileDataSwitch(false))
3058 .item(modemInfo("", "Offline", "gsm-3g-disabled"))
3059 .item(cellularSettings())
3060 )
3061@@ -1022,6 +1083,8 @@
3062 .mode(mh::MenuItemMatcher::Mode::starts_with)
3063 .item(flightModeSwitch(false))
3064 .item(mh::MenuItemMatcher()
3065+ .section()
3066+ .item(mobileDataSwitch(true))
3067 .item(modemInfo("", "fake.tel", "gsm-3g-high", false, "network-cellular-pre-edge"))
3068 .item(cellularSettings())
3069 )
3070@@ -1068,6 +1131,8 @@
3071 .mode(mh::MenuItemMatcher::Mode::starts_with)
3072 .item(flightModeSwitch(false))
3073 .item(mh::MenuItemMatcher()
3074+ .section()
3075+ .item(mobileDataSwitch())
3076 .item(modemInfo("", "fake.tel", "gsm-3g-low"))
3077 .item(cellularSettings())
3078 )
3079@@ -1116,6 +1181,8 @@
3080 .mode(mh::MenuItemMatcher::Mode::starts_with)
3081 .item(flightModeSwitch(true))
3082 .item(mh::MenuItemMatcher()
3083+ .section()
3084+ .item(mobileDataSwitch())
3085 .item(modemInfo("", "Offline", "gsm-3g-disabled"))
3086 .item(cellularSettings())
3087 )
3088@@ -1162,6 +1229,8 @@
3089 .mode(mh::MenuItemMatcher::Mode::starts_with)
3090 .item(flightModeSwitch(true))
3091 .item(mh::MenuItemMatcher()
3092+ .section()
3093+ .item(mobileDataSwitch())
3094 .item(modemInfo("", "Offline", "gsm-3g-disabled"))
3095 .item(cellularSettings())
3096 )
3097@@ -1199,6 +1268,8 @@
3098 .mode(mh::MenuItemMatcher::Mode::starts_with)
3099 .item(flightModeSwitch(false))
3100 .item(mh::MenuItemMatcher()
3101+ .section()
3102+ .item(mobileDataSwitch())
3103 .item(modemInfo("", "fake.tel", "gsm-3g-low"))
3104 .item(cellularSettings())
3105 )
3106@@ -1347,6 +1418,8 @@
3107 .mode(mh::MenuItemMatcher::Mode::starts_with)
3108 .item(flightModeSwitch(false))
3109 .item(mh::MenuItemMatcher()
3110+ .section()
3111+ .item(mobileDataSwitch())
3112 .item(modemInfo("", "fake.tel", "gsm-3g-full"))
3113 .item(cellularSettings())
3114 )
3115@@ -1392,6 +1465,8 @@
3116 .mode(mh::MenuItemMatcher::Mode::starts_with)
3117 .item(flightModeSwitch(false))
3118 .item(mh::MenuItemMatcher()
3119+ .section()
3120+ .item(mobileDataSwitch())
3121 .item(modemInfo("", "No SIM", "no-simcard"))
3122 .item(cellularSettings())
3123 )
3124@@ -1431,6 +1506,8 @@
3125 .mode(mh::MenuItemMatcher::Mode::starts_with)
3126 .item(flightModeSwitch(false))
3127 .item(mh::MenuItemMatcher()
3128+ .section()
3129+ .item(mobileDataSwitch())
3130 .item(modemInfo("", "No SIM", "no-simcard"))
3131 .item(cellularSettings())
3132 )
3133@@ -1607,6 +1684,8 @@
3134 .mode(mh::MenuItemMatcher::Mode::starts_with)
3135 .item(flightModeSwitch(false))
3136 .item(mh::MenuItemMatcher()
3137+ .section()
3138+ .item(mobileDataSwitch())
3139 .item(modemInfo("", "No SIM", "no-simcard"))
3140 .item(cellularSettings())
3141 )
3142@@ -1764,6 +1843,8 @@
3143 .mode(mh::MenuItemMatcher::Mode::starts_with)
3144 .item(flightModeSwitch(false))
3145 .item(mh::MenuItemMatcher()
3146+ .section()
3147+ .item(mobileDataSwitch())
3148 .item(modemInfo("", "No SIM", "no-simcard"))
3149 .item(cellularSettings())
3150 )
3151@@ -1792,6 +1873,8 @@
3152 .mode(mh::MenuItemMatcher::Mode::starts_with)
3153 .item(flightModeSwitch(false))
3154 .item(mh::MenuItemMatcher()
3155+ .section()
3156+ .item(mobileDataSwitch())
3157 .item(modemInfo("", "No SIM", "no-simcard"))
3158 .item(cellularSettings())
3159 )
3160@@ -1821,6 +1904,8 @@
3161 .mode(mh::MenuItemMatcher::Mode::starts_with)
3162 .item(flightModeSwitch(false))
3163 .item(mh::MenuItemMatcher()
3164+ .section()
3165+ .item(mobileDataSwitch())
3166 .item(modemInfo("", "No SIM", "no-simcard"))
3167 .item(cellularSettings())
3168 )
3169@@ -1849,6 +1934,8 @@
3170 .mode(mh::MenuItemMatcher::Mode::starts_with)
3171 .item(flightModeSwitch(false))
3172 .item(mh::MenuItemMatcher()
3173+ .section()
3174+ .item(mobileDataSwitch())
3175 .item(modemInfo("", "No SIM", "no-simcard"))
3176 .item(cellularSettings())
3177 )
3178@@ -1897,6 +1984,8 @@
3179 .mode(mh::MenuItemMatcher::Mode::starts_with)
3180 .item(flightModeSwitch(false))
3181 .item(mh::MenuItemMatcher()
3182+ .section()
3183+ .item(mobileDataSwitch())
3184 .item(modemInfo("", "No SIM", "no-simcard"))
3185 .item(cellularSettings())
3186 )
3187@@ -1954,6 +2043,8 @@
3188 .mode(mh::MenuItemMatcher::Mode::starts_with)
3189 .item(flightModeSwitch())
3190 .item(mh::MenuItemMatcher()
3191+ .section()
3192+ .item(mobileDataSwitch(true))
3193 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-high", false, "network-cellular-hspa"))
3194 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-low"))
3195 .item(cellularSettings())
3196@@ -1971,6 +2062,8 @@
3197 .mode(mh::MenuItemMatcher::Mode::starts_with)
3198 .item(flightModeSwitch())
3199 .item(mh::MenuItemMatcher()
3200+ .section()
3201+ .item(mobileDataSwitch(true))
3202 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-high", false, "network-cellular-edge"))
3203 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-low"))
3204 .item(cellularSettings())
3205@@ -1979,8 +2072,10 @@
3206 ).match());
3207
3208 // Set second SIM as the active data connection
3209- setConnectionManagerProperty(firstModem(), "Powered", false);
3210- setConnectionManagerProperty(secondModem, "Powered", true);
3211+ auto connectivity = newConnectivity();
3212+ auto modems = getSortedModems(*connectivity);
3213+ auto sim2 = getModemSim(*modems, 1);
3214+ connectivity->setSimForMobileData(sim2);
3215
3216 // Now we should have a 3G icon
3217 EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3218@@ -1989,6 +2084,8 @@
3219 .mode(mh::MenuItemMatcher::Mode::starts_with)
3220 .item(flightModeSwitch())
3221 .item(mh::MenuItemMatcher()
3222+ .section()
3223+ .item(mobileDataSwitch(true))
3224 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-high"))
3225 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-low", false, "network-cellular-3g"))
3226 .item(cellularSettings())
3227@@ -2028,6 +2125,8 @@
3228 .mode(mh::MenuItemMatcher::Mode::starts_with)
3229 .item(flightModeSwitch())
3230 .item(mh::MenuItemMatcher()
3231+ .section()
3232+ .item(mobileDataSwitch(false))
3233 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-low"))
3234 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-high"))
3235 .item(cellularSettings())
3236@@ -2048,6 +2147,8 @@
3237 .mode(mh::MenuItemMatcher::Mode::starts_with)
3238 .item(flightModeSwitch())
3239 .item(mh::MenuItemMatcher()
3240+ .section()
3241+ .item(mobileDataSwitch(true))
3242 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-low"))
3243 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-high", false, "network-cellular-3g"))
3244 .item(cellularSettings())
3245@@ -2071,6 +2172,8 @@
3246 .mode(mh::MenuItemMatcher::Mode::starts_with)
3247 .item(flightModeSwitch())
3248 .item(mh::MenuItemMatcher()
3249+ .section()
3250+ .item(mobileDataSwitch(true))
3251 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-low"))
3252 .item(modemInfo("SIM 2", "fake.tel", "gsm-3g-high", false, "network-cellular-3g"))
3253 .item(cellularSettings())
3254@@ -2110,6 +2213,8 @@
3255 .mode(mh::MenuItemMatcher::Mode::starts_with)
3256 .item(flightModeSwitch())
3257 .item(mh::MenuItemMatcher()
3258+ .section()
3259+ .item(mobileDataSwitch())
3260 .item(modemInfo("", "SIM Locked", "simcard-locked", true)
3261 .pass_through_activate("x-canonical-modem-locked-action")
3262 )
3263@@ -2201,6 +2306,8 @@
3264 .mode(mh::MenuItemMatcher::Mode::starts_with)
3265 .item(flightModeSwitch())
3266 .item(mh::MenuItemMatcher()
3267+ .section()
3268+ .item(mobileDataSwitch())
3269 .item(modemInfo("", "SIM Locked", "simcard-locked", true)
3270 .pass_through_activate("x-canonical-modem-locked-action")
3271 )
3272@@ -2256,6 +2363,8 @@
3273 .mode(mh::MenuItemMatcher::Mode::starts_with)
3274 .item(flightModeSwitch())
3275 .item(mh::MenuItemMatcher()
3276+ .section()
3277+ .item(mobileDataSwitch())
3278 .item(modemInfo("", "SIM Locked", "simcard-locked", true)
3279 .pass_through_activate("x-canonical-modem-locked-action")
3280 )
3281@@ -2322,6 +2431,8 @@
3282 .mode(mh::MenuItemMatcher::Mode::starts_with)
3283 .item(flightModeSwitch())
3284 .item(mh::MenuItemMatcher()
3285+ .section()
3286+ .item(mobileDataSwitch())
3287 .item(modemInfo("SIM 1", "SIM Locked", "simcard-locked", true)
3288 .pass_through_activate("x-canonical-modem-locked-action")
3289 )
3290@@ -2378,6 +2489,8 @@
3291 .mode(mh::MenuItemMatcher::Mode::starts_with)
3292 .item(flightModeSwitch())
3293 .item(mh::MenuItemMatcher()
3294+ .section()
3295+ .item(mobileDataSwitch())
3296 .item(modemInfo("SIM 1", "SIM Locked", "simcard-locked", true))
3297 .item(modemInfo("SIM 2", "SIM Locked", "simcard-locked", true)
3298 .pass_through_activate("x-canonical-modem-locked-action")
3299@@ -2444,6 +2557,8 @@
3300 .mode(mh::MenuItemMatcher::Mode::starts_with)
3301 .item(flightModeSwitch())
3302 .item(mh::MenuItemMatcher()
3303+ .section()
3304+ .item(mobileDataSwitch())
3305 .item(modemInfo("", "SIM Locked", "simcard-locked", true)
3306 .pass_through_activate("x-canonical-modem-locked-action")
3307 )
3308@@ -2527,6 +2642,8 @@
3309 .mode(mh::MenuItemMatcher::Mode::starts_with)
3310 .item(flightModeSwitch())
3311 .item(mh::MenuItemMatcher()
3312+ .section()
3313+ .item(mobileDataSwitch())
3314 .item(modemInfo("", "SIM Locked", "simcard-locked", true)
3315 .pass_through_activate("x-canonical-modem-locked-action")
3316 )
3317@@ -2809,6 +2926,8 @@
3318 .mode(mh::MenuItemMatcher::Mode::starts_with)
3319 .item(flightModeSwitch())
3320 .item(mh::MenuItemMatcher()
3321+ .section()
3322+ .item(mobileDataSwitch())
3323 .item(modemInfo("SIM 1", "fake.tel", "gsm-3g-full"))
3324 .item(modemInfo("SIM 2", "SIM Locked", "simcard-locked", true)
3325 .pass_through_activate("x-canonical-modem-locked-action")
3326@@ -3068,4 +3187,144 @@
3327 notificationsSpy.clear();
3328 }
3329
3330+TEST_F(TestIndicator, CellularData_1)
3331+{
3332+ auto con = newConnectivity();
3333+
3334+ ASSERT_NO_THROW(startIndicator());
3335+
3336+ // Check that the indicator switch is enabled when we are not in flightmode
3337+ // and there is a SIM for mobile data set.
3338+
3339+ con->setMobileDataEnabled(true);
3340+ con->setFlightMode(false);
3341+ con->setSimForMobileData(getModemSim(*con->modems(), 0));
3342+
3343+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3344+ .item(mh::MenuItemMatcher()
3345+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3346+ .submenu()
3347+ .item(flightModeSwitch())
3348+ .item(mh::MenuItemMatcher()
3349+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3350+ .section()
3351+ .item(mobileDataSwitch(true)
3352+ .enabled(true)
3353+ )
3354+ )
3355+ ).match());
3356+
3357+ // Check that the indicator switch is disabled when we are in flightmode
3358+ con->setFlightMode(true);
3359+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3360+ .item(mh::MenuItemMatcher()
3361+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3362+ .submenu()
3363+ .item(flightModeSwitch())
3364+ .item(mh::MenuItemMatcher()
3365+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3366+ .section()
3367+ .item(mobileDataSwitch(true)
3368+ .enabled(false)
3369+ )
3370+ )
3371+ ).match());
3372+
3373+ // Check that the indicator switch is disabled when there is no SIM for mobile data set.
3374+ con->setFlightMode(false);
3375+ con->setSimForMobileData(nullptr);
3376+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3377+ .item(mh::MenuItemMatcher()
3378+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3379+ .submenu()
3380+ .item(flightModeSwitch())
3381+ .item(mh::MenuItemMatcher()
3382+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3383+ .section()
3384+ .item(mobileDataSwitch(true)
3385+ .enabled(false)
3386+ )
3387+ )
3388+ ).match());
3389+}
3390+
3391+TEST_F(TestIndicator, CellularData_2)
3392+{
3393+ auto con = newConnectivity();
3394+
3395+ ASSERT_NO_THROW(startIndicator());
3396+
3397+ // Check that Connectivity::mobileDataEnabled follows the indicator switch
3398+
3399+ con->setMobileDataEnabled(true);
3400+ con->setFlightMode(false);
3401+ con->setSimForMobileData(getModemSim(*con->modems(), 0));
3402+ QTest::qWait(250);
3403+ QSignalSpy spy(con.get(), SIGNAL(mobileDataEnabledUpdated(bool)));
3404+
3405+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3406+ .item(mh::MenuItemMatcher()
3407+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3408+ .submenu()
3409+ .item(flightModeSwitch())
3410+ .item(mh::MenuItemMatcher()
3411+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3412+ .section()
3413+ .item(mobileDataSwitch(true)
3414+ .activate()
3415+ )
3416+ )
3417+ ).match());
3418+
3419+ WAIT_FOR_SIGNALS(spy, 1);
3420+ EXPECT_EQ(spy[0], QVariantList() << QVariant(false));
3421+ spy.clear();
3422+
3423+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3424+ .item(mh::MenuItemMatcher()
3425+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3426+ .submenu()
3427+ .item(flightModeSwitch())
3428+ .item(mh::MenuItemMatcher()
3429+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3430+ .section()
3431+ .item(mobileDataSwitch(false)
3432+ .activate()
3433+ )
3434+ )
3435+ ).match());
3436+
3437+ WAIT_FOR_SIGNALS(spy, 1);
3438+ EXPECT_EQ(spy[0], QVariantList() << QVariant(true));
3439+
3440+
3441+ // Check that indicator switch follows the Connectivity::mobileDataEnabled
3442+
3443+ con->setMobileDataEnabled(true);
3444+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3445+ .item(mh::MenuItemMatcher()
3446+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3447+ .submenu()
3448+ .item(flightModeSwitch())
3449+ .item(mh::MenuItemMatcher()
3450+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3451+ .section()
3452+ .item(mobileDataSwitch(true))
3453+ )
3454+ ).match());
3455+
3456+ con->setMobileDataEnabled(false);
3457+ EXPECT_MATCHRESULT(mh::MenuMatcher(phoneParameters())
3458+ .item(mh::MenuItemMatcher()
3459+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3460+ .submenu()
3461+ .item(flightModeSwitch())
3462+ .item(mh::MenuItemMatcher()
3463+ .mode(mh::MenuItemMatcher::Mode::starts_with)
3464+ .section()
3465+ .item(mobileDataSwitch(false))
3466+ )
3467+ ).match());
3468+}
3469+
3470 } // namespace

Subscribers

People subscribed via source and target branches