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

Proposed by Antti Kaijanmäki on 2014-07-01
Status: Merged
Approved by: Charles Kerr on 2014-08-07
Approved revision: 363
Merge reported by: Antti Kaijanmäki
Merged at revision: not available
Proposed branch: lp:~unity-api-team/indicator-network/modeminfo
Merge into: lp:indicator-network/14.10
Diff against target: 1162 lines (+584/-244)
12 files modified
debian/control (+1/-1)
network/CMakeLists.txt (+1/-0)
network/menuitems/modem-info-item.cpp (+148/-0)
network/menuitems/modem-info-item.h (+56/-0)
network/menumodel-cpp/menu-merger.h (+8/-1)
network/modem.cpp (+119/-103)
network/modem.h (+40/-2)
network/root-state.cpp (+75/-102)
network/service.h (+6/-6)
network/wwan-link-item.cpp (+96/-25)
network/wwan-link-item.h (+2/-0)
network/wwan-section.cpp (+32/-4)
To merge this branch: bzr merge lp:~unity-api-team/indicator-network/modeminfo
Reviewer Review Type Date Requested Status
Pete Woods (community) 2014-07-01 Approve on 2014-08-07
Nick Dedekind (community) Needs Fixing on 2014-08-07
PS Jenkins bot (community) continuous-integration Approve on 2014-08-07
Charles Kerr (community) Approve on 2014-08-07
Review via email: mp+225160@code.launchpad.net

Commit message

Add ModemInfoItem.

Description of the change

ModemInfoItem.

also requires:
https://code.launchpad.net/~unity-api-team/unity8/modeminfo/+merge/225159
https://code.launchpad.net/~unity-api-team/unity8/default-indicator-page-loader-visible-fix/+merge/228943

silo: https://launchpad.net/~ci-train-ppa-service/+archive/ubuntu/landing-001

New indicator item that displays modem information and allows unlocking of a cellular modems.

Example of the different variations:
http://imgur.com/W52T6nV

Actual result when combined with the indicator:
http://imgur.com/XK0fEWt

To post a comment you must log in.
Pete Woods (pete-woods) wrote :

LGTM.

review: Approve
Charles Kerr (charlesk) wrote :

Tested on N4, seems to be working as advertised. :-)

review: Approve
Nick Dedekind (nick-dedekind) wrote :

On Mako

https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim1.png
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim2.png
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim3.png
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim4.png
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim5.png
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim6.png
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim7.png

locked_sim1.png) this is how it comes up on boot. looks ok
locked_sim2.png) after unlocking phone. Note it still says "SIM Locked"
locked_sim3.png) restart indicator-network
locked_sim4.png) called the phone when it was in state 3. rejected
locked_sim5.png) restart indicator-network. called phone again. Can see the notification for accepting call, but see is still "Offline" & no strength icon
locked_sim6.png) restarted phone. came up without a locked sim icon in panel as in 1
locked_sim7.png) resarted again and unlocked. finally went into searching, then picked up a network. But it doesn't match with the designs you provided where there is the phone number above the carrier. There is no way to tell the sims apart if connected on same network.

/usr/share/ofono/scripts/list-modems output for each state.
1) http://paste.ubuntu.com/7969273/
2) http://paste.ubuntu.com/7969275/
3) http://paste.ubuntu.com/7969276/
4) http://paste.ubuntu.com/7969279/
5) http://paste.ubuntu.com/7969280/
6) can't reproduce
7) http://paste.ubuntu.com/7969282/

review: Needs Fixing
360. By Antti Kaijanmäki on 2014-08-06

Forgot to bind to the modem online property in the panel icon side.

361. By Antti Kaijanmäki on 2014-08-07

add default sim identifiers and make sure modems are ordered correctly in the menu.

Antti Kaijanmäki (kaijanmaki) wrote :

> On Mako
>
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim1.png
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim2.png
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim3.png
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim4.png
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim5.png
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim6.png
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim7.png
>
> locked_sim1.png) this is how it comes up on boot. looks ok
> locked_sim2.png) after unlocking phone. Note it still says "SIM Locked"
> locked_sim3.png) restart indicator-network
> locked_sim4.png) called the phone when it was in state 3. rejected
> locked_sim5.png) restart indicator-network. called phone again. Can see the
> notification for accepting call, but see is still "Offline" & no strength icon
> locked_sim6.png) restarted phone. came up without a locked sim icon in panel
> as in 1
> locked_sim7.png) resarted again and unlocked. finally went into searching,
> then picked up a network.

Thank you for in-depth testing!

I nailed a couple of bugs and hopefully all of the above problems are now solved.

> But it doesn't match with the designs you provided
> where there is the phone number above the carrier.

The phone number is not always available. We need to investigate a bit more to figure out what additional information to have in there.

> There is no way to tell the
> sims apart if connected on same network.

Agreed.

I added default SIM identifiers (SIM 1, SIM 2) which are visible when using a dual sim device.

on a single sim device there is no reason to show the identifier as there is only one sim.

362. By Antti Kaijanmäki on 2014-08-07

review adjustments.

363. By Antti Kaijanmäki on 2014-08-07

make sure cellular icons are ordered correctly in the panel.

Charles Kerr (charlesk) wrote :

Code inspection LGTM after r362 + r363, thanks for the fixes.

I do not have dual sim so I have /not/ done Real World testing on this -- DO NOT merge this based on my approval until Nick's had another pass at it :)

review: Approve
Nick Dedekind (nick-dedekind) wrote :

Seems to be a little better now, but after a few tries of rebooting phone and unlocking I got this:

This is after unlocking. Note missing text & disabled signal icon in panel.
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim8.png

After restarting indicator-network.
https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim9.png

The state text should never be empty. If it's in an unknown state, it should say "Unknown".

review: Needs Fixing
364. By Antti Kaijanmäki on 2014-08-07

Improve the panel modemTechIcon handling a bit on dual sim.

365. By Antti Kaijanmäki on 2014-08-07

Handle NetworkRegistration::Status::unknown better.

Antti Kaijanmäki (kaijanmaki) wrote :

> Seems to be a little better now, but after a few tries of rebooting phone and
> unlocking I got this:
>
> This is after unlocking. Note missing text & disabled signal icon in panel.
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim8.png

OK. seems your phone gets an unknown state from networkregistration and unfortunately the unknown case was accidentally clearing the connectivity-icon instead of status icon. Fixed now.

> After restarting indicator-network.
> https://dl.dropboxusercontent.com/u/85539674/locked_sim/locked_sim9.png
>
> The state text should never be empty. If it's in an unknown state, it should
> say "Unknown".

Agreed and fixed.

Pete Woods (pete-woods) wrote :

The last two changes look sensible to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-07-22 20:21:50 +0000
3+++ debian/control 2014-08-07 11:23:41 +0000
4@@ -41,7 +41,7 @@
5 ubuntu-mobile-icons (>= 13.04+13.10.20131014),
6 # For apport hook
7 python3-xdg,
8- unity8 (>= 7.82),
9+ unity8 (>= 8.00+14.10.20140806),
10 Conflicts: chewie,
11 indicators-client-plugin-network,
12 Description: Systems settings menu service - Network indicator
13
14=== modified file 'network/CMakeLists.txt'
15--- network/CMakeLists.txt 2014-05-22 08:32:45 +0000
16+++ network/CMakeLists.txt 2014-08-07 11:23:41 +0000
17@@ -28,6 +28,7 @@
18
19 menuitems/access-point-item.h
20 menuitems/item.h
21+ menuitems/modem-info-item.cpp
22 menuitems/section.h
23 menuitems/switch-item.h
24 menuitems/text-item.h
25
26=== added file 'network/menuitems/modem-info-item.cpp'
27--- network/menuitems/modem-info-item.cpp 1970-01-01 00:00:00 +0000
28+++ network/menuitems/modem-info-item.cpp 2014-08-07 11:23:41 +0000
29@@ -0,0 +1,148 @@
30+/*
31+ * Copyright (C) 2014 Canonical, Ltd.
32+ *
33+ * This program is free software: you can redistribute it and/or modify it
34+ * under the terms of the GNU General Public License version 3, as published
35+ * by the Free Software Foundation.
36+ *
37+ * This program is distributed in the hope that it will be useful, but
38+ * WITHOUT ANY WARRANTY; without even the implied warranties of
39+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
40+ * PURPOSE. See the GNU General Public License for more details.
41+ *
42+ * You should have received a copy of the GNU General Public License along
43+ * with this program. If not, see <http://www.gnu.org/licenses/>.
44+ *
45+ * Authors:
46+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
47+ */
48+
49+#include "modem-info-item.h"
50+
51+class ModemInfoItem::Private
52+{
53+public:
54+ core::Signal<void> m_unlock;
55+
56+ std::vector<core::Connection> m_connections;
57+
58+ Action::Ptr m_actionStatusLabel;
59+ Action::Ptr m_actionStatusIcon;
60+ Action::Ptr m_actionConnectivityIcon;
61+ Action::Ptr m_actionSimIdentifier;
62+ Action::Ptr m_actionRoaming;
63+ Action::Ptr m_actionLocked;
64+
65+ MenuItem::Ptr m_item;
66+};
67+
68+ModemInfoItem::ModemInfoItem()
69+{
70+ d.reset(new Private);
71+
72+ static int id = 0;
73+ ++id; /// @todo guard me.
74+
75+ std::string actionIdBase = "modem." + std::to_string(id);
76+
77+ std::string statusLabelActionId = actionIdBase + "::status-label";
78+ std::string statusIconActionId = actionIdBase + "::status-icon";
79+ std::string connectivityIconActionId = actionIdBase + "::connectivity-icon";
80+ std::string simIdentifierActionId = actionIdBase + "::sim-identifier-label";
81+ std::string roamingActionId = actionIdBase + "::roaming";
82+ std::string lockedActionId = actionIdBase + "::locked";
83+
84+ d->m_item = std::make_shared<MenuItem>();
85+
86+ d->m_item->setAttribute("x-canonical-type", TypedVariant<std::string>("com.canonical.indicator.network.modeminfoitem"));
87+ d->m_item->setAttribute("x-canonical-modem-status-label-action", TypedVariant<std::string>("indicator." + statusLabelActionId));
88+ d->m_item->setAttribute("x-canonical-modem-status-icon-action", TypedVariant<std::string>("indicator." + statusIconActionId));
89+ d->m_item->setAttribute("x-canonical-modem-connectivity-icon-action", TypedVariant<std::string>("indicator." + connectivityIconActionId));
90+ d->m_item->setAttribute("x-canonical-modem-sim-identifier-label-action", TypedVariant<std::string>("indicator." + simIdentifierActionId));
91+ d->m_item->setAttribute("x-canonical-modem-roaming-action", TypedVariant<std::string>("indicator." + roamingActionId));
92+ d->m_item->setAttribute("x-canonical-modem-locked-action", TypedVariant<std::string>("indicator." + lockedActionId));
93+
94+
95+
96+ d->m_actionStatusLabel = std::make_shared<Action>(statusLabelActionId,
97+ nullptr,
98+ TypedVariant<std::string>());
99+ d->m_actionStatusIcon = std::make_shared<Action>(statusIconActionId,
100+ nullptr,
101+ TypedVariant<std::string>());
102+ d->m_actionConnectivityIcon = std::make_shared<Action>(connectivityIconActionId,
103+ nullptr,
104+ TypedVariant<std::string>());
105+ d->m_actionSimIdentifier = std::make_shared<Action>(simIdentifierActionId,
106+ nullptr,
107+ TypedVariant<std::string>());
108+ d->m_actionRoaming = std::make_shared<Action>(roamingActionId,
109+ nullptr,
110+ TypedVariant<bool>(false));
111+ d->m_actionLocked = std::make_shared<Action>(lockedActionId,
112+ nullptr,
113+ TypedVariant<bool>(false));
114+ m_actionGroup->add(d->m_actionStatusLabel);
115+ m_actionGroup->add(d->m_actionStatusIcon);
116+ m_actionGroup->add(d->m_actionConnectivityIcon);
117+ m_actionGroup->add(d->m_actionSimIdentifier);
118+ m_actionGroup->add(d->m_actionRoaming);
119+ m_actionGroup->add(d->m_actionLocked);
120+
121+ d->m_actionLocked->activated().connect([this](Variant){ d->m_unlock(); });
122+}
123+
124+ModemInfoItem::~ModemInfoItem()
125+{
126+
127+}
128+
129+void
130+ModemInfoItem::setStatusIcon(const std::string &name)
131+{
132+ d->m_actionStatusIcon->setState(TypedVariant<std::string>(name));
133+}
134+
135+void
136+ModemInfoItem::setStatusText(const std::string &value)
137+{
138+ d->m_actionStatusLabel->setState(TypedVariant<std::string>(value));
139+}
140+
141+void
142+ModemInfoItem::setConnectivityIcon(const std::string &name)
143+{
144+ d->m_actionConnectivityIcon->setState(TypedVariant<std::string>(name));
145+}
146+
147+void
148+ModemInfoItem::setSimIdentifierText(const std::string &value)
149+
150+{
151+ d->m_actionSimIdentifier->setState(TypedVariant<std::string>(value));
152+}
153+
154+void
155+ModemInfoItem::setLocked(bool value)
156+{
157+ d->m_actionLocked->setState(TypedVariant<bool>(value));
158+}
159+
160+void
161+ModemInfoItem::setRoaming(bool value)
162+{
163+ d->m_actionRoaming->setState(TypedVariant<bool>(value));
164+}
165+
166+MenuItem::Ptr
167+ModemInfoItem::menuItem()
168+{
169+ return d->m_item;
170+}
171+
172+core::Signal<void> &
173+ModemInfoItem::unlock()
174+{
175+ return d->m_unlock;
176+}
177+
178
179=== added file 'network/menuitems/modem-info-item.h'
180--- network/menuitems/modem-info-item.h 1970-01-01 00:00:00 +0000
181+++ network/menuitems/modem-info-item.h 2014-08-07 11:23:41 +0000
182@@ -0,0 +1,56 @@
183+/*
184+ * Copyright (C) 2014 Canonical, Ltd.
185+ *
186+ * This program is free software: you can redistribute it and/or modify it
187+ * under the terms of the GNU General Public License version 3, as published
188+ * by the Free Software Foundation.
189+ *
190+ * This program is distributed in the hope that it will be useful, but
191+ * WITHOUT ANY WARRANTY; without even the implied warranties of
192+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
193+ * PURPOSE. See the GNU General Public License for more details.
194+ *
195+ * You should have received a copy of the GNU General Public License along
196+ * with this program. If not, see <http://www.gnu.org/licenses/>.
197+ *
198+ * Authors:
199+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
200+ */
201+
202+#ifndef MODEM_INFO_ITEM_H
203+#define MODEM_INFO_ITEM_H
204+
205+#include "item.h"
206+#include "menumodel-cpp/action.h"
207+#include "menumodel-cpp/menu-item.h"
208+#include "menumodel-cpp/gio-helpers/variant.h"
209+
210+#include <core/signal.h>
211+
212+#include <functional>
213+#include <vector>
214+
215+class ModemInfoItem : public Item
216+{
217+ class Private;
218+ std::unique_ptr<Private> d;
219+
220+public:
221+ typedef std::shared_ptr<ModemInfoItem> Ptr;
222+
223+ ModemInfoItem();
224+ virtual ~ModemInfoItem();
225+
226+ void setStatusIcon(const std::string &name);
227+ void setStatusText(const std::string &value);
228+ void setConnectivityIcon(const std::string &name);
229+ void setSimIdentifierText(const std::string &value);
230+ void setLocked(bool value);
231+ void setRoaming(bool value);
232+
233+ virtual MenuItem::Ptr menuItem();
234+
235+ core::Signal<void> &unlock();
236+};
237+
238+#endif // MODEM_INFO_ITEM_H
239
240=== modified file 'network/menumodel-cpp/menu-merger.h'
241--- network/menumodel-cpp/menu-merger.h 2014-04-23 13:18:25 +0000
242+++ network/menumodel-cpp/menu-merger.h 2014-08-07 11:23:41 +0000
243@@ -127,7 +127,14 @@
244 m_startPositions.erase(*menu);
245 m_gmodelToMenu.erase(*menu);
246 m_menus.erase(std::remove(m_menus.begin(), m_menus.end(), menu), m_menus.end());
247- }
248+ }
249+
250+ void clear()
251+ {
252+ std::vector<MenuModel::Ptr> tmp = m_menus;
253+ for (auto menu : tmp)
254+ remove(menu);
255+ }
256
257 operator GMenuModel*() { return G_MENU_MODEL(m_gmenu.get()); }
258 };
259
260=== modified file 'network/modem.cpp'
261--- network/modem.cpp 2014-05-02 14:05:12 +0000
262+++ network/modem.cpp 2014-08-07 11:23:41 +0000
263@@ -22,49 +22,91 @@
264 class Modem::Private
265 {
266 public:
267+ core::Property<bool> m_online;
268+
269 org::ofono::Interface::Modem::Ptr m_ofonoModem;
270 core::Property<Modem::SimStatus> m_simStatus;
271 core::Property<Modem::PinType> m_requiredPin;
272 core::Property<std::map<Modem::PinType, std::uint8_t>> m_retries;
273- core::Property<std::string> m_subscriberIdentity;
274
275 core::Property<std::string> m_operatorName;
276 core::Property<org::ofono::Interface::NetworkRegistration::Status> m_status;
277 core::Property<std::int8_t> m_strength;
278 core::Property<org::ofono::Interface::NetworkRegistration::Technology> m_technology;
279
280+ core::Property<std::string> m_simIdentifier;
281+ int m_index = -1;
282+
283 void networkRegistrationChanged(org::ofono::Interface::NetworkRegistration::Ptr netreg);
284 void simManagerChanged(org::ofono::Interface::SimManager::Ptr simmgr);
285
286- void simPresentChanged(bool value);
287- void pinRequiredChanged(org::ofono::Interface::SimManager::PinType pin);
288- void retriesChanged(std::map<org::ofono::Interface::SimManager::PinType, std::uint8_t> retries) ;
289+ void update();
290 };
291
292 void
293-Modem::Private::networkRegistrationChanged(org::ofono::Interface::NetworkRegistration::Ptr netreg)
294+Modem::Private::update()
295 {
296+ auto simmgr = m_ofonoModem->simManager.get();
297+ if (simmgr) {
298+ // update requiredPin
299+ switch(simmgr->pinRequired.get())
300+ {
301+ case org::ofono::Interface::SimManager::PinType::none:
302+ m_requiredPin.set(PinType::none);
303+ break;
304+ case org::ofono::Interface::SimManager::PinType::pin:
305+ m_requiredPin.set(PinType::pin);
306+ break;
307+ case org::ofono::Interface::SimManager::PinType::puk:
308+ m_requiredPin.set(PinType::puk);
309+ break;
310+ default:
311+ throw std::runtime_error("Ofono requires a PIN we have not been prepared to handle (" +
312+ org::ofono::Interface::SimManager::pin2str(simmgr->pinRequired.get()) +
313+ "). Bailing out.");
314+ }
315+
316+ // update retries
317+ std::map<Modem::PinType, std::uint8_t> tmp;
318+ for (auto element : simmgr->retries.get()) {
319+ switch(element.first) {
320+ case org::ofono::Interface::SimManager::PinType::pin:
321+ tmp[Modem::PinType::pin] = element.second;
322+ break;
323+ case org::ofono::Interface::SimManager::PinType::puk:
324+ tmp[Modem::PinType::puk] = element.second;
325+ break;
326+ default:
327+ // don't care
328+ break;
329+ }
330+ }
331+ m_retries.set(tmp);
332+
333+ // update simStatus
334+ if (!simmgr->present.get()) {
335+ m_simStatus.set(SimStatus::missing);
336+ } else if (m_requiredPin == PinType::none){
337+ m_simStatus.set(SimStatus::ready);
338+ } else {
339+ if (m_retries->count(PinType::puk) != 0 && m_retries->at(PinType::puk) == 0)
340+ m_simStatus.set(SimStatus::permanentlyLocked);
341+ else
342+ m_simStatus.set(SimStatus::locked);
343+ }
344+
345+ } else {
346+ m_requiredPin.set(PinType::none);
347+ m_retries.set({});
348+ m_simStatus.set(SimStatus::missing);
349+ }
350+
351+ auto netreg = m_ofonoModem->networkRegistration.get();
352 if (netreg) {
353- netreg->operatorName.changed().connect([this](std::string value){
354- m_operatorName.set(value);
355- });
356 m_operatorName.set(netreg->operatorName.get());
357-
358- netreg->status.changed().connect([this](org::ofono::Interface::NetworkRegistration::Status value){
359- m_status.set(value);
360- });
361 m_status.set(netreg->status.get());
362-
363- netreg->strength.changed().connect([this](std::int8_t value){
364- m_strength.set(value);
365- });
366 m_strength.set(netreg->strength.get());
367-
368- netreg->technology.changed().connect([this](org::ofono::Interface::NetworkRegistration::Technology value){
369- m_technology.set(value);
370- });
371 m_technology.set(netreg->technology.get());
372-
373 } else {
374 m_operatorName.set("");
375 m_status.set(org::ofono::Interface::NetworkRegistration::Status::unknown);
376@@ -73,96 +115,58 @@
377 }
378 }
379
380+void
381+Modem::Private::networkRegistrationChanged(org::ofono::Interface::NetworkRegistration::Ptr netreg)
382+{
383+ if (netreg) {
384+ netreg->operatorName.changed().connect(std::bind(&Private::update, this));
385+ netreg->status.changed().connect(std::bind(&Private::update, this));
386+ netreg->strength.changed().connect(std::bind(&Private::update, this));
387+ netreg->technology.changed().connect(std::bind(&Private::update, this));
388+ }
389+ update();
390+}
391+
392
393 void
394 Modem::Private::simManagerChanged(org::ofono::Interface::SimManager::Ptr simmgr)
395 {
396 if (simmgr) {
397- simmgr->present.changed().connect(std::bind(&Private::simPresentChanged, this, std::placeholders::_1));
398- simPresentChanged(simmgr->present.get());
399-
400- simmgr->pinRequired.changed().connect(std::bind(&Private::pinRequiredChanged, this, std::placeholders::_1));
401- pinRequiredChanged(simmgr->pinRequired.get());
402-
403- simmgr->retries.changed().connect(std::bind(&Private::retriesChanged, this, std::placeholders::_1));
404- retriesChanged(simmgr->retries.get());
405-
406- /// @todo subscriberIdentity
407-
408- } else {
409- m_simStatus.set(SimStatus::offline);
410- m_requiredPin.set(PinType::none);
411- m_retries.set({});
412- }
413-}
414-
415-void
416-Modem::Private::pinRequiredChanged(org::ofono::Interface::SimManager::PinType pin)
417-{
418- switch(pin)
419- {
420- case org::ofono::Interface::SimManager::PinType::none:
421- m_requiredPin.set(PinType::none);
422- m_simStatus.set(SimStatus::ready);
423- break;
424- case org::ofono::Interface::SimManager::PinType::pin:
425- m_requiredPin.set(PinType::pin);
426- m_simStatus.set(SimStatus::locked);
427- break;
428- case org::ofono::Interface::SimManager::PinType::puk:
429- m_requiredPin.set(PinType::puk);
430- m_simStatus.set(SimStatus::locked);
431- break;
432- default:
433- throw std::runtime_error("Ofono requires a PIN we have not been prepared to handle (" +
434- org::ofono::Interface::SimManager::pin2str(pin) +
435- "). Bailing out.");
436- }
437-}
438-
439-void
440-Modem::Private::retriesChanged(std::map<org::ofono::Interface::SimManager::PinType, std::uint8_t> retries)
441-{
442- std::map<Modem::PinType, std::uint8_t> tmp;
443- for (auto element : retries) {
444- switch(element.first) {
445- case org::ofono::Interface::SimManager::PinType::pin:
446- tmp[Modem::PinType::pin] = element.second;
447- break;
448- case org::ofono::Interface::SimManager::PinType::puk:
449- tmp[Modem::PinType::puk] = element.second;
450- break;
451- default:
452- // don't care
453- break;
454- }
455- }
456- m_retries.set(tmp);
457-}
458-
459-void
460-Modem::Private::simPresentChanged(bool value)
461-{
462- if (!value) {
463- m_simStatus.set(SimStatus::missing);
464- }
465-}
466-
467+ simmgr->present.changed().connect(std::bind(&Private::update, this));
468+ simmgr->pinRequired.changed().connect(std::bind(&Private::update, this));
469+ simmgr->retries.changed().connect(std::bind(&Private::update, this));
470+ }
471+ update();
472+}
473
474 Modem::Modem(org::ofono::Interface::Modem::Ptr ofonoModem)
475 {
476 d.reset(new Private);
477 d->m_ofonoModem = ofonoModem;
478
479+ d->m_online.set(d->m_ofonoModem->online.get());
480+ d->m_ofonoModem->online.changed().connect([this](bool value){
481+ d->m_online.set(value);
482+ });
483+
484 d->simManagerChanged(d->m_ofonoModem->simManager.get());
485- d->m_ofonoModem->simManager.changed().connect([this](org::ofono::Interface::SimManager::Ptr value){
486- d->simManagerChanged(value);
487- });
488+ d->m_ofonoModem->simManager.changed().connect(std::bind(&Private::simManagerChanged, d.get(), std::placeholders::_1));
489
490 d->networkRegistrationChanged(d->m_ofonoModem->networkRegistration.get());
491- d->m_ofonoModem->networkRegistration.changed().connect([this](org::ofono::Interface::NetworkRegistration::Ptr value){
492- d->networkRegistrationChanged(value);
493- });
494+ d->m_ofonoModem->networkRegistration.changed().connect(std::bind(&Private::networkRegistrationChanged, d.get(), std::placeholders::_1));
495+
496+ /// @todo hook up with system-settings to allow changing the identifier.
497+ /// for now just provide the defaults
498+ const auto path = ofonoModem->object->path().as_string();
499+ if (path == "/ril_0") {
500+ d->m_simIdentifier.set("SIM 1");
501+ d->m_index = 1;
502+ } else if (path == "/ril_1") {
503+ d->m_simIdentifier.set("SIM 2");
504+ d->m_index = 2;
505+ } else {
506+ d->m_simIdentifier.set(path);
507+ }
508 }
509
510 Modem::~Modem()
511@@ -240,6 +244,12 @@
512 throw std::logic_error("code should not be reached.");
513 }
514
515+const core::Property<bool> &
516+Modem::online()
517+{
518+ return d->m_online;
519+}
520+
521 const core::Property<Modem::SimStatus> &
522 Modem::simStatus()
523 {
524@@ -259,12 +269,6 @@
525 }
526
527 const core::Property<std::string> &
528-Modem::subscriberIdentity()
529-{
530- return d->m_subscriberIdentity;
531-}
532-
533-const core::Property<std::string> &
534 Modem::operatorName()
535 {
536 return d->m_operatorName;
537@@ -287,3 +291,15 @@
538 {
539 return d->m_technology;
540 }
541+const core::Property<std::string> &
542+Modem::simIdentifier()
543+{
544+ return d->m_simIdentifier;
545+}
546+
547+int
548+Modem::index()
549+{
550+ return d->m_index;
551+}
552+
553
554=== modified file 'network/modem.h'
555--- network/modem.h 2014-04-23 13:18:25 +0000
556+++ network/modem.h 2014-08-07 11:23:41 +0000
557@@ -42,7 +42,6 @@
558
559 enum class SimStatus
560 {
561- offline,
562 missing,
563 error,
564 locked,
565@@ -70,17 +69,56 @@
566 const std::string &oldPin,
567 const std::string &newPin);
568
569+ const core::Property<bool> &online();
570
571 const core::Property<SimStatus> &simStatus();
572 const core::Property<PinType> &requiredPin();
573 const core::Property<std::map<PinType, std::uint8_t>> &retries();
574- const core::Property<std::string> &subscriberIdentity();
575
576 const core::Property<std::string> &operatorName();
577 const core::Property<org::ofono::Interface::NetworkRegistration::Status> &status();
578 const core::Property<std::int8_t> &strength();
579 const core::Property<org::ofono::Interface::NetworkRegistration::Technology> &technology();
580
581+ const core::Property<std::string> &simIdentifier();
582+ int index();
583+
584+ static const std::string strengthIcon(int8_t strength)
585+ {
586+ /* Using same values as used by Android, not linear (LP: #1329945)*/
587+ if (strength >= 39)
588+ return "gsm-3g-full";
589+ else if (strength >= 26)
590+ return "gsm-3g-high";
591+ else if (strength >= 16)
592+ return "gsm-3g-medium";
593+ else if (strength >= 6)
594+ return "gsm-3g-low";
595+ else
596+ return "gsm-3g-none";
597+ }
598+
599+ static const std::string technologyIcon(org::ofono::Interface::NetworkRegistration::Technology tech)
600+ {
601+ switch (tech){
602+ case org::ofono::Interface::NetworkRegistration::Technology::notAvailable:
603+ case org::ofono::Interface::NetworkRegistration::Technology::gsm:
604+ return "network-cellular-pre-edge";
605+ case org::ofono::Interface::NetworkRegistration::Technology::edge:
606+ return "network-cellular-edge";
607+ case org::ofono::Interface::NetworkRegistration::Technology::umts:
608+ return "network-cellular-3g";
609+ case org::ofono::Interface::NetworkRegistration::Technology::hspa:
610+ return "network-cellular-hspa";
611+ /// @todo oFono can't tell us about hspa+ yet
612+ //case org::ofono::Interface::NetworkRegistration::Technology::hspaplus:
613+ // break;
614+ case org::ofono::Interface::NetworkRegistration::Technology::lte:
615+ return "network-cellular-lte";
616+ }
617+ // shouldn't be reached
618+ return "";
619+ }
620 };
621
622 #endif
623
624=== modified file 'network/root-state.cpp'
625--- network/root-state.cpp 2014-06-17 12:27:05 +0000
626+++ network/root-state.cpp 2014-08-07 11:23:41 +0000
627@@ -33,7 +33,6 @@
628 ModemManager::Ptr m_modemManager;
629 core::Property<Variant> m_state;
630
631- std::string m_preLabel;
632 std::string m_label;
633
634 /// @todo multiple adapters etc..
635@@ -41,15 +40,11 @@
636
637 std::string m_modemTechIcon;
638
639- bool m_inFlightMode;
640- bool m_roaming;
641-
642 std::map<Modem::Ptr, std::string> m_cellularIcons;
643
644 Private() = delete;
645 Private(std::shared_ptr<networking::Manager> manager, ModemManager::Ptr modemManager);
646
647- void flightModeChanged(networking::Manager::FlightModeStatus status);
648 void modemsChanged(const std::set<Modem::Ptr> &modems);
649
650 void updateModem(Modem::WeakPtr weakModem);
651@@ -62,39 +57,23 @@
652
653 RootState::Private::Private(std::shared_ptr<networking::Manager> manager, ModemManager::Ptr modemManager)
654 : m_manager{manager},
655- m_modemManager{modemManager},
656- m_roaming{false}
657+ m_modemManager{modemManager}
658 {
659- m_manager->flightMode().changed().connect(std::bind(&Private::flightModeChanged, this, std::placeholders::_1));
660- flightModeChanged(m_manager->flightMode().get());
661+ m_manager->flightMode().changed().connect(std::bind(&Private::updateRootState, this));
662
663 m_modemManager->modems().changed().connect(std::bind(&Private::modemsChanged, this, std::placeholders::_1));
664 modemsChanged(m_modemManager->modems().get());
665
666 m_manager->status().changed().connect(std::bind(&Private::updateNetworkingIcon, this));
667 m_manager->links().changed().connect(std::bind(&Private::updateNetworkingIcon, this));
668+
669+ // will also call updateRootState()
670 updateNetworkingIcon();
671 }
672
673 void
674-RootState::Private::flightModeChanged(networking::Manager::FlightModeStatus status)
675-{
676- switch(status) {
677- case networking::Manager::FlightModeStatus::off:
678- m_inFlightMode = false;
679- break;
680- case networking::Manager::FlightModeStatus::on:
681- m_inFlightMode = true;
682- break;
683- }
684- updateRootState();
685-}
686-
687-void
688 RootState::Private::modemsChanged(const std::set<Modem::Ptr> &modems)
689 {
690- /// @todo we have to address the correct ordering of the modems
691-
692 std::set<Modem::Ptr> current;
693 for (auto element : m_cellularIcons)
694 current.insert(element.first);
695@@ -112,6 +91,7 @@
696 m_cellularIcons.erase(modem);
697
698 for (auto modem : added) {
699+ modem->online().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
700 modem->simStatus().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
701 modem->status().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
702 modem->technology().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
703@@ -129,90 +109,56 @@
704 return;
705 }
706
707- /// @todo multisim for all of these
708- m_preLabel.clear();
709- m_roaming = false;
710 m_modemTechIcon.clear();
711-
712 m_cellularIcons[modem] = "";
713
714+ if (!modem->online().get()) {
715+ // modem offline, nothing to show
716+ updateRootState();
717+ return;
718+ }
719
720 switch(modem->simStatus().get()) {
721- case Modem::SimStatus::offline:
722- /// @todo show something.
723- break;
724 case Modem::SimStatus::missing:
725- m_preLabel = _("No SIM");
726+ // no need to show anything in the panel
727 break;
728 case Modem::SimStatus::error:
729- m_preLabel = _("SIM Error");
730+ m_cellularIcons[modem] = "simcard-error";
731 break;
732 case Modem::SimStatus::locked:
733 case Modem::SimStatus::permanentlyLocked:
734- /// @todo handle perm blocked somehow
735- m_preLabel = _("SIM Locked");
736+ m_cellularIcons[modem] = "simcard-locked";
737 break;
738 case Modem::SimStatus::ready:
739 {
740 switch (modem->status().get()) {
741 case org::ofono::Interface::NetworkRegistration::Status::unregistered:
742- /// @todo show something?
743- break;
744- case org::ofono::Interface::NetworkRegistration::Status::denied:
745- /// @todo maybe show something like "Denied" ?
746- m_preLabel = _("No Signal");
747- break;
748 case org::ofono::Interface::NetworkRegistration::Status::unknown:
749 case org::ofono::Interface::NetworkRegistration::Status::searching:
750+ m_cellularIcons[modem] = "gsm-3g-disabled";
751+ break;
752+ case org::ofono::Interface::NetworkRegistration::Status::denied:
753+ /// @todo we might need network-error for this
754+ m_cellularIcons[modem] = "gsm-3g-disabled";
755+ break;
756 case org::ofono::Interface::NetworkRegistration::Status::registered:
757- /// @todo show something?
758- break;
759 case org::ofono::Interface::NetworkRegistration::Status::roaming:
760- /// @todo multisim
761- m_roaming = true;
762- break;
763- }
764-
765- auto strength = modem->strength().get();
766- /* Using same values as used by Android, not linear (LP: #1329945)*/
767- if (strength >= 39)
768- m_cellularIcons[modem] = "gsm-3g-full";
769- else if (strength >= 26)
770- m_cellularIcons[modem] = "gsm-3g-high";
771- else if (strength >= 16)
772- m_cellularIcons[modem] = "gsm-3g-medium";
773- else if (strength >= 6)
774- m_cellularIcons[modem] = "gsm-3g-low";
775- else
776- m_cellularIcons[modem] = "gsm-3g-none";
777-
778- switch (modem->technology().get()){
779- case org::ofono::Interface::NetworkRegistration::Technology::notAvailable:
780- /// @todo check this..
781- // "network-cellular-pre-edge"
782- // a11ydesc = _("Network (cellular, %s)").printf(current_protocol)
783- break;
784- case org::ofono::Interface::NetworkRegistration::Technology::gsm:
785- m_modemTechIcon = "network-cellular-pre-edge";
786- break;
787- case org::ofono::Interface::NetworkRegistration::Technology::edge:
788- m_modemTechIcon = "network-cellular-edge";
789- break;
790- case org::ofono::Interface::NetworkRegistration::Technology::umts:
791- m_modemTechIcon = "network-cellular-3g";
792- break;
793- case org::ofono::Interface::NetworkRegistration::Technology::hspa:
794- m_modemTechIcon = "network-cellular-hspa";
795- break;
796- /// @todo oFono can't tell us about hspa+ yet
797- //case org::ofono::Interface::NetworkRegistration::Technology::hspaplus:
798- // break;
799- case org::ofono::Interface::NetworkRegistration::Technology::lte:
800- m_modemTechIcon = "network-cellular-lte";
801- break;
802- }
803- // we might have changed the modem tech icon which affects the networkingIcon.
804- updateNetworkingIcon();
805+ if (modem->strength().get() != 0) {
806+ m_cellularIcons[modem] = Modem::strengthIcon(modem->strength().get());
807+ /// @todo need to revise this once the modems are part of the connectivity-api
808+ /// this might get us wrong results on dual-sim
809+ if (modem->index() == 1) {
810+ m_modemTechIcon = Modem::technologyIcon(modem->technology().get());
811+ }
812+ } else {
813+ m_cellularIcons[modem] = "gsm-3g-no-service";
814+
815+ }
816+
817+ // we might have changed the modem tech icon which affects the networkingIcon.
818+ updateNetworkingIcon();
819+ break;
820+ }
821 break;
822 }}
823
824@@ -241,8 +187,12 @@
825
826 auto wifiLink = std::dynamic_pointer_cast<networking::wifi::Link>(link);
827
828- int strength = wifiLink->activeAccessPoint().get()->strength().get();
829- bool secured = wifiLink->activeAccessPoint().get()->secured();
830+ int strength = -1;
831+ bool secured = false;
832+ if (wifiLink->activeAccessPoint().get()) {
833+ strength = wifiLink->activeAccessPoint().get()->strength().get();
834+ secured = wifiLink->activeAccessPoint().get()->secured();
835+ }
836
837 /// @todo deal with a11ydesc
838 // gchar *a11ydesc = nullptr;
839@@ -305,15 +255,41 @@
840 std::vector<std::string> icons;
841 std::map<std::string, Variant> state;
842
843- if (m_inFlightMode)
844+ switch(m_manager->flightMode().get()) {
845+ case networking::Manager::FlightModeStatus::off:
846+ break;
847+ case networking::Manager::FlightModeStatus::on:
848 icons.push_back("airplane-mode");
849-
850- for (auto icon : m_cellularIcons)
851- if (!icon.second.empty())
852- icons.push_back(icon.second);
853-
854- if (m_roaming)
855- icons.push_back("network-cellular-roaming");
856+ break;
857+ }
858+
859+ auto compare = [](int lhs, int rhs ){
860+ // make sure index() == -1 goes as leftmost cellular icon
861+ if (lhs == -1 && rhs == -1)
862+ return false;
863+ if (lhs == -1)
864+ return false;
865+ if (rhs == -1)
866+ return true;
867+ return lhs < rhs;
868+ };
869+ std::multimap<int, std::string, decltype(compare)> sorted(compare);
870+
871+ for (auto pair : m_cellularIcons) {
872+ sorted.insert(std::make_pair(pair.first->index(), pair.second));
873+ }
874+ for (auto pair : sorted) {
875+ if (!pair.second.empty())
876+ icons.push_back(pair.second);
877+ }
878+
879+ // if any of the modems is roaming, show the roaming icon
880+ for (auto modem : m_modemManager->modems().get()) {
881+ if (modem->status().get() == org::ofono::Interface::NetworkRegistration::Status::roaming) {
882+ icons.push_back("network-cellular-roaming");
883+ break;
884+ }
885+ }
886
887 if (!m_networkingIcon.empty()) {
888
889@@ -328,9 +304,6 @@
890 icons.push_back(m_networkingIcon);
891 }
892
893- if (!m_preLabel.empty())
894- state["pre-label"] = TypedVariant<std::string>(m_preLabel);
895-
896 if (!m_label.empty())
897 state["label"] = TypedVariant<std::string>(m_label);
898
899
900=== modified file 'network/service.h'
901--- network/service.h 2014-05-16 19:39:19 +0000
902+++ network/service.h 2014-08-07 11:23:41 +0000
903@@ -112,18 +112,18 @@
904 m_phoneMenu->addSection(m_quickAccessSection);
905 m_phoneGreeterMenu->addSection(m_quickAccessSection);
906
907+ m_wwanSection = std::make_shared<WwanSection>(m_modemManager);
908+ m_desktopMenu->addSection(m_wwanSection);
909+ m_desktopGreeterMenu->addSection(m_wwanSection);
910+ m_phoneMenu->addSection(m_wwanSection);
911+ m_phoneGreeterMenu->addSection(m_wwanSection);
912+
913 m_wifiSection = std::make_shared<WifiSection>(m_manager);
914 m_desktopMenu->addSection(m_wifiSection);
915 m_desktopGreeterMenu->addSection(m_wifiSection);
916 m_phoneMenu->addSection(m_wifiSection);
917 m_phoneGreeterMenu->addSection(m_wifiSection);
918
919- m_wwanSection = std::make_shared<WwanSection>(m_modemManager);
920- m_desktopMenu->addSection(m_wwanSection);
921- m_desktopGreeterMenu->addSection(m_wwanSection);
922- m_phoneMenu->addSection(m_wwanSection);
923- m_phoneGreeterMenu->addSection(m_wwanSection);
924-
925 m_desktopMenuExporter.reset(new MenuExporter(m_sessionBus, "/com/canonical/indicator/network/desktop", m_desktopMenu->menu()));
926 m_desktopGreeterMenuExporter.reset(new MenuExporter(m_sessionBus, "/com/canonical/indicator/network/desktop_greeter", m_desktopGreeterMenu->menu()));
927 m_desktopWifiSettingsMenuExporter.reset(new MenuExporter(m_sessionBus, "/com/canonical/indicator/network/desktop_wifi_settings", m_wifiSection->settingsModel()));
928
929=== modified file 'network/wwan-link-item.cpp'
930--- network/wwan-link-item.cpp 2014-05-21 17:56:25 +0000
931+++ network/wwan-link-item.cpp 2014-08-07 11:23:41 +0000
932@@ -19,7 +19,7 @@
933
934 #include "wwan-link-item.h"
935
936-#include "menuitems/text-item.h"
937+#include "menuitems/modem-info-item.h"
938
939 #include "menumodel-cpp/menu.h"
940
941@@ -33,13 +33,14 @@
942 Modem::Ptr m_modem;
943 ModemManager::Ptr m_modemManager;
944
945- TextItem::Ptr m_unlockSim;
946- bool m_wasLocked;
947+ ModemInfoItem::Ptr m_infoItem;
948+
949+ core::Property<bool> m_showIdentifier;
950
951 Private() = delete;
952 Private(Modem::Ptr modem, ModemManager::Ptr modemManager);
953
954- void simStatusChanged(Modem::SimStatus status);
955+ void update();
956 void unlockSim();
957 };
958
959@@ -50,33 +51,97 @@
960 m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
961 m_menu = std::make_shared<Menu>();
962
963- /// @todo add stuff to control the link
964-
965- m_unlockSim = std::make_shared<TextItem>(_("Unlock SIM…"), "sim", "unlock");
966- m_unlockSim->activated().connect(std::bind(&ModemManager::unlockModem, m_modemManager.get(), m_modem));
967-
968- m_actionGroupMerger->add(*m_unlockSim);
969-
970- m_wasLocked = false;
971- m_modem->simStatus().changed().connect(std::bind(&Private::simStatusChanged, this, std::placeholders::_1));
972- simStatusChanged(m_modem->simStatus().get());
973+ m_infoItem = std::make_shared<ModemInfoItem>();
974+ m_infoItem->unlock().connect(std::bind(&ModemManager::unlockModem, m_modemManager.get(), m_modem));
975+
976+ m_actionGroupMerger->add(*m_infoItem);
977+ m_menu->append(*m_infoItem);
978+
979+ m_showIdentifier.set(false);
980+ m_showIdentifier.changed().connect(std::bind(&Private::update, this));
981+
982+ m_modem->online().changed().connect(std::bind(&Private::update, this));
983+ m_modem->simStatus().changed().connect(std::bind(&Private::update, this));
984+ m_modem->operatorName().changed().connect(std::bind(&Private::update, this));
985+ m_modem->status().changed().connect(std::bind(&Private::update, this));
986+ m_modem->strength().changed().connect(std::bind(&Private::update, this));
987+ m_modem->technology().changed().connect(std::bind(&Private::update, this));
988+ m_modem->simIdentifier().changed().connect(std::bind(&Private::update, this));
989+ update();
990 }
991
992 void
993-WwanLinkItem::Private::simStatusChanged(Modem::SimStatus status)
994+WwanLinkItem::Private::update()
995 {
996- if (status == Modem::SimStatus::locked) {
997- if (!m_wasLocked) {
998- //m_actionGroupMerger->add(*m_unlockSim);
999- m_menu->append(*m_unlockSim);
1000- m_wasLocked = true;
1001- }
1002+ if (m_showIdentifier.get()) {
1003+ m_infoItem->setSimIdentifierText(m_modem->simIdentifier().get());
1004 } else {
1005- if (m_wasLocked) {
1006- //m_actionGroupMerger->remove(*m_unlockSim);
1007- m_menu->remove(m_menu->find(*m_unlockSim));
1008- m_wasLocked = false;
1009+ m_infoItem->setSimIdentifierText("");
1010+ }
1011+ /// @todo implement me.
1012+ m_infoItem->setConnectivityIcon("");
1013+
1014+ switch(m_modem->simStatus().get()) {
1015+ case Modem::SimStatus::missing:
1016+ m_infoItem->setStatusIcon("no-simcard");
1017+ m_infoItem->setStatusText(_("No SIM"));
1018+ m_infoItem->setLocked(false);
1019+ m_infoItem->setRoaming(false);
1020+ break;
1021+ case Modem::SimStatus::error:
1022+ m_infoItem->setStatusIcon("simcard-error");
1023+ m_infoItem->setStatusText(_("SIM Error"));
1024+ m_infoItem->setLocked(false);
1025+ m_infoItem->setRoaming(false);
1026+ break;
1027+ case Modem::SimStatus::locked:
1028+ case Modem::SimStatus::permanentlyLocked:
1029+ m_infoItem->setStatusIcon("simcard-locked");
1030+ m_infoItem->setStatusText(_("SIM Locked"));
1031+ m_infoItem->setLocked(true);
1032+ m_infoItem->setRoaming(false);
1033+ break;
1034+ case Modem::SimStatus::ready:
1035+ m_infoItem->setLocked(false);
1036+ m_infoItem->setRoaming(false);
1037+
1038+ if (m_modem->online().get()) {
1039+ switch (m_modem->status().get()) {
1040+ case org::ofono::Interface::NetworkRegistration::Status::unregistered:
1041+ m_infoItem->setStatusIcon("gsm-3g-disabled");
1042+ m_infoItem->setStatusText(_("Unregistered"));
1043+ break;
1044+ case org::ofono::Interface::NetworkRegistration::Status::unknown:
1045+ m_infoItem->setStatusIcon("gsm-3g-disabled");
1046+ m_infoItem->setStatusText(_("Unknown"));
1047+ break;
1048+ case org::ofono::Interface::NetworkRegistration::Status::denied:
1049+ m_infoItem->setStatusIcon("gsm-3g-disabled");
1050+ m_infoItem->setStatusText(_("Denied"));
1051+ break;
1052+ case org::ofono::Interface::NetworkRegistration::Status::searching:
1053+ m_infoItem->setStatusIcon("gsm-3g-disabled");
1054+ m_infoItem->setStatusText(_("Searching"));
1055+ break;
1056+ case org::ofono::Interface::NetworkRegistration::Status::roaming:
1057+ m_infoItem->setRoaming(true);
1058+ /* fallthrough */
1059+ case org::ofono::Interface::NetworkRegistration::Status::registered:
1060+ if (m_modem->strength().get() != 0) {
1061+ m_infoItem->setStatusIcon(Modem::strengthIcon(m_modem->strength().get()));
1062+ m_infoItem->setStatusText(m_modem->operatorName());
1063+ } else {
1064+ m_infoItem->setStatusIcon("gsm-3g-no-service");
1065+ m_infoItem->setStatusText(_("No Signal"));
1066+ }
1067+ break;
1068+ }
1069+ } else {
1070+ m_infoItem->setStatusIcon("gsm-3g-disabled");
1071+ m_infoItem->setStatusText(_("Offline"));
1072 }
1073+
1074+ break;
1075 }
1076 }
1077
1078@@ -99,3 +164,9 @@
1079 {
1080 return d->m_menu;
1081 }
1082+
1083+void
1084+WwanLinkItem::showSimIdentifier(bool value)
1085+{
1086+ d->m_showIdentifier.set(value);
1087+}
1088
1089=== modified file 'network/wwan-link-item.h'
1090--- network/wwan-link-item.h 2014-04-23 13:18:25 +0000
1091+++ network/wwan-link-item.h 2014-08-07 11:23:41 +0000
1092@@ -37,6 +37,8 @@
1093 // from Section
1094 virtual ActionGroup::Ptr actionGroup();
1095 virtual MenuModel::Ptr menuModel();
1096+
1097+ void showSimIdentifier(bool value);
1098 };
1099
1100 #endif // WWAN_LINK_ITEM_H
1101
1102=== modified file 'network/wwan-section.cpp'
1103--- network/wwan-section.cpp 2014-05-16 12:38:53 +0000
1104+++ network/wwan-section.cpp 2014-08-07 11:23:41 +0000
1105@@ -92,8 +92,6 @@
1106 void
1107 WwanSection::Private::modemsChanged(const std::set<Modem::Ptr> &modems)
1108 {
1109- /// @todo we have to address the correct ordering of the modems
1110-
1111 std::set<Modem::Ptr> current;
1112 for (auto element : m_items)
1113 current.insert(element.first);
1114@@ -118,9 +116,31 @@
1115
1116 for (auto modem : added) {
1117 auto item = std::make_shared<WwanLinkItem>(modem, m_modemManager);
1118- m_linkMenuMerger->append(*item);
1119+
1120+ m_items.push_back(std::make_pair(modem, item));
1121 m_actionGroupMerger->add(*item);
1122- m_items.push_back(std::make_pair(modem, item));
1123+
1124+ // for now just throw everything away and rebuild
1125+ /// @todo add MenuMerger::insert() and ::find()
1126+ m_linkMenuMerger->clear();
1127+
1128+ auto compare = [](int lhs, int rhs ){
1129+ // make sure index() == -1 goes to the bottom of the menu
1130+ if (lhs == -1 && rhs == -1)
1131+ return false;
1132+ if (lhs == -1)
1133+ return false;
1134+ if (rhs == -1)
1135+ return true;
1136+ return lhs < rhs;
1137+ };
1138+ std::multimap<int, WwanLinkItem::Ptr, decltype(compare)> sorted(compare);
1139+
1140+ for (auto pair : m_items) {
1141+ sorted.insert(std::make_pair(pair.first->index(), pair.second));
1142+ }
1143+ for (auto pair : sorted)
1144+ m_linkMenuMerger->append(*(pair.second));
1145 }
1146
1147 if (modems.size() == 0) {
1148@@ -129,6 +149,14 @@
1149 if (m_bottomMenu->find(*m_openCellularSettings) == m_bottomMenu->end())
1150 m_bottomMenu->append(*m_openCellularSettings);
1151 }
1152+
1153+ if (m_items.size() > 1) {
1154+ for(auto i : m_items)
1155+ i.second->showSimIdentifier(true);
1156+ } else {
1157+ for(auto i : m_items)
1158+ i.second->showSimIdentifier(false);
1159+ }
1160 }
1161
1162 WwanSection::WwanSection(ModemManager::Ptr modemManager)

Subscribers

People subscribed via source and target branches