Skip to content

Commit ca97f23

Browse files
authored
Merge pull request #23 from spiiroin/jb56945_imei_numbers
[deviceinfo] Add imeiNumbers property. JB#56945
2 parents de83a9d + 518f0e6 commit ca97f23

File tree

4 files changed

+174
-8
lines changed

4 files changed

+174
-8
lines changed

rpm/nemo-qml-plugin-systemsettings.spec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ BuildRequires: pkgconfig(libsystemd)
3737
BuildRequires: pkgconfig(sailfishusermanager)
3838
BuildRequires: qt5-qttools-linguist
3939
BuildRequires: pkgconfig(openssl)
40+
BuildRequires: pkgconfig(qofono-qt5) >= 0.105
4041

4142
%description
4243
%{summary}.

src/deviceinfo.cpp

Lines changed: 135 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,16 @@
3434
#include <QSet>
3535

3636
#include <ssusysinfo.h>
37+
#include <qofonomanager.h>
38+
#include <qofonomodem.h>
3739

38-
class DeviceInfoPrivate
40+
class DeviceInfoPrivate: public QObject
3941
{
42+
Q_OBJECT
4043
public:
41-
DeviceInfoPrivate();
44+
DeviceInfoPrivate(DeviceInfo *deviceInfo, bool synchronousInit);
4245
~DeviceInfoPrivate();
46+
QStringList imeiNumbers();
4347

4448
QSet<DeviceInfo::Feature> m_features;
4549
QSet<Qt::Key> m_keys;
@@ -51,9 +55,31 @@ class DeviceInfoPrivate
5155
QString m_osName;
5256
QString m_osVersion;
5357
QString m_adaptationVersion;
58+
private slots:
59+
void modemsChanged(const QStringList &modems);
60+
void modemSerialChanged(const QString &serial);
61+
void updateModemProperties();
62+
private:
63+
void modemAdded(const QString &modem);
64+
void modemRemoved(const QString &modem);
65+
QSharedPointer<QOfonoManager> ofonoManager();
66+
void updateModemPropertiesLater();
67+
68+
DeviceInfo *q_ptr;
69+
bool m_synchronousInit;
70+
QSharedPointer<QOfonoManager> m_ofonoManager;
71+
QHash<QString, QSharedPointer<QOfonoModem> > m_modemHash;
72+
QStringList m_modemList;
73+
QStringList m_imeiNumbers;
74+
QTimer *m_updateModemPropertiesTimer;
75+
Q_DISABLE_COPY(DeviceInfoPrivate);
76+
Q_DECLARE_PUBLIC(DeviceInfo);
5477
};
5578

56-
DeviceInfoPrivate::DeviceInfoPrivate()
79+
DeviceInfoPrivate::DeviceInfoPrivate(DeviceInfo *deviceInfo, bool synchronousInit)
80+
: q_ptr(deviceInfo)
81+
, m_synchronousInit(synchronousInit)
82+
, m_updateModemPropertiesTimer(nullptr)
5783
{
5884
ssusysinfo_t *si = ssusysinfo_create();
5985

@@ -90,10 +116,107 @@ DeviceInfoPrivate::~DeviceInfoPrivate()
90116
{
91117
}
92118

119+
QStringList DeviceInfoPrivate::imeiNumbers()
120+
{
121+
/* Trigger on-demand ofono tracking and
122+
* evaluate initial property values. */
123+
ofonoManager();
124+
125+
return m_imeiNumbers;
126+
}
127+
128+
QSharedPointer<QOfonoManager> DeviceInfoPrivate::ofonoManager()
129+
{
130+
if (m_ofonoManager.isNull()) {
131+
m_ofonoManager = QOfonoManager::instance(m_synchronousInit);
132+
connect(&*m_ofonoManager, &QOfonoManager::modemsChanged, this, &DeviceInfoPrivate::modemsChanged);
133+
134+
m_updateModemPropertiesTimer = new QTimer(this);
135+
m_updateModemPropertiesTimer->setInterval(50);
136+
m_updateModemPropertiesTimer->setSingleShot(true);
137+
connect(m_updateModemPropertiesTimer, &QTimer::timeout, this, &DeviceInfoPrivate::updateModemProperties);
138+
139+
QStringList modems(m_ofonoManager->modems());
140+
for (auto iter = modems.cbegin(); iter != modems.cend(); ++iter)
141+
modemAdded(*iter);
142+
updateModemProperties();
143+
}
144+
return m_ofonoManager;
145+
}
146+
147+
void DeviceInfoPrivate::updateModemPropertiesLater()
148+
{
149+
if (!m_updateModemPropertiesTimer->isActive())
150+
m_updateModemPropertiesTimer->start();
151+
}
152+
153+
void DeviceInfoPrivate::updateModemProperties()
154+
{
155+
QStringList imeiNumbers;
156+
for (auto iter = m_modemList.cbegin(); iter != m_modemList.cend(); ++iter) {
157+
QString imei(m_modemHash[*iter]->serial());
158+
if (!imei.isEmpty())
159+
imeiNumbers.append(imei);
160+
}
161+
if (m_imeiNumbers != imeiNumbers) {
162+
m_imeiNumbers = imeiNumbers;
163+
Q_Q(DeviceInfo);
164+
emit q->imeiNumbersChanged();
165+
}
166+
m_updateModemPropertiesTimer->stop();
167+
}
168+
169+
void DeviceInfoPrivate::modemRemoved(const QString &modemName)
170+
{
171+
QSharedPointer<QOfonoModem> modem(m_modemHash.take(modemName));
172+
if (!modem.isNull()) {
173+
disconnect(&*modem, &QOfonoModem::serialChanged, this, &DeviceInfoPrivate::modemSerialChanged);
174+
m_modemList.removeOne(modemName);
175+
updateModemPropertiesLater();
176+
}
177+
}
178+
179+
void DeviceInfoPrivate::modemAdded(const QString &modemName)
180+
{
181+
if (!m_modemHash.contains(modemName)) {
182+
QSharedPointer<QOfonoModem> modem(QOfonoModem::instance(modemName, m_synchronousInit));
183+
connect(&*modem, &QOfonoModem::serialChanged, this, &DeviceInfoPrivate::modemSerialChanged);
184+
m_modemHash[modemName] = modem;
185+
m_modemList.append(modemName);
186+
updateModemPropertiesLater();
187+
}
188+
}
189+
190+
void DeviceInfoPrivate::modemsChanged(const QStringList &modems)
191+
{
192+
QSet<QString> previous(m_modemList.toSet());
193+
QSet<QString> current(modems.toSet());
194+
QSet<QString> added(current - previous);
195+
QSet<QString> removed(previous - current);
196+
for (auto iter = removed.cbegin(); iter != removed.cend(); ++iter)
197+
modemRemoved(*iter);
198+
for (auto iter = added.cbegin(); iter != added.cend(); ++iter)
199+
modemAdded(*iter);
200+
}
201+
202+
void DeviceInfoPrivate::modemSerialChanged(const QString &serial)
203+
{
204+
Q_UNUSED(serial);
205+
updateModemPropertiesLater();
206+
}
207+
208+
DeviceInfo::DeviceInfo(bool synchronousInit, QObject *parent)
209+
: QObject(parent)
210+
, d_ptr(new DeviceInfoPrivate(this, synchronousInit))
211+
{
212+
Q_D(const DeviceInfo);
213+
}
214+
93215
DeviceInfo::DeviceInfo(QObject *parent)
94216
: QObject(parent)
95-
, d_ptr(new DeviceInfoPrivate())
217+
, d_ptr(new DeviceInfoPrivate(this, false))
96218
{
219+
Q_D(const DeviceInfo);
97220
}
98221

99222
DeviceInfo::~DeviceInfo()
@@ -161,3 +284,11 @@ QString DeviceInfo::adaptationVersion() const
161284
Q_D(const DeviceInfo);
162285
return d->m_adaptationVersion;
163286
}
287+
288+
QStringList DeviceInfo::imeiNumbers()
289+
{
290+
Q_D(DeviceInfo);
291+
return d->imeiNumbers();
292+
}
293+
294+
#include "deviceinfo.moc"

src/deviceinfo.h

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
3030
*/
3131

32-
#ifndef DEVICEINFO_H
33-
#define DEVICEINFO_H
32+
#ifndef NEMO_SYSTEMSETTINGS_DEVICEINFO_H_
33+
#define NEMO_SYSTEMSETTINGS_DEVICEINFO_H_
3434

3535
#include <QObject>
3636

@@ -51,6 +51,7 @@ class SYSTEMSETTINGS_EXPORT DeviceInfo: public QObject
5151
Q_PROPERTY(QString osName READ osName CONSTANT)
5252
Q_PROPERTY(QString osVersion READ osVersion CONSTANT)
5353
Q_PROPERTY(QString adaptationVersion READ adaptationVersion CONSTANT)
54+
Q_PROPERTY(QStringList imeiNumbers READ imeiNumbers NOTIFY imeiNumbersChanged)
5455

5556
public:
5657
enum Feature {
@@ -103,7 +104,8 @@ class SYSTEMSETTINGS_EXPORT DeviceInfo: public QObject
103104
};
104105
Q_ENUM(Feature)
105106

106-
DeviceInfo(QObject *parent = 0);
107+
DeviceInfo(bool synchronousInit, QObject *parent = nullptr);
108+
DeviceInfo(QObject *parent = nullptr);
107109
~DeviceInfo();
108110
Q_INVOKABLE bool hasFeature(DeviceInfo::Feature feature) const;
109111
Q_INVOKABLE bool hasHardwareKey(Qt::Key key) const;
@@ -220,11 +222,42 @@ class SYSTEMSETTINGS_EXPORT DeviceInfo: public QObject
220222
*/
221223
QString adaptationVersion() const;
222224

225+
/*!
226+
* List of IMEI number strings
227+
*
228+
* Note: Access is limited to users in
229+
* \l {https://github.com/sailfishos/sailfish-setup} {sailfish-phone}
230+
* group. Additionally sandboxed applications need
231+
* \l {https://github.com/sailfishos/sailjail-permissions} {Phone}
232+
* permission. If these requirements are not met, an empty list
233+
* is returned.
234+
*
235+
* Obtained by enumerating modems exposed on D-Bus by OFono service.
236+
*
237+
* Normally enumeration is done asynchronously in background and
238+
* empty list is returned until enumeration is finished.
239+
*
240+
* If DeviceInfo object is created using synchronousInit=true,
241+
* constructor blocks while getting the initial values - which may
242+
* be useful when dealing with procedural logic.
243+
*
244+
* If/when OFono is not running, an empty list is returned regardless
245+
* of whether asynchronous or synchronous init is used.
246+
*
247+
* Should be functionally equivalent with obtaining data via:
248+
* QDeviceInfo::imei()
249+
* QDeviceInfo::imeiCount()
250+
*/
251+
QStringList imeiNumbers();
252+
253+
Q_SIGNALS:
254+
void imeiNumbersChanged();
255+
223256
private:
224257

225258
DeviceInfoPrivate *d_ptr;
226259
Q_DISABLE_COPY(DeviceInfo)
227260
Q_DECLARE_PRIVATE(DeviceInfo)
228261
};
229262

230-
#endif /* DEVICEINFO_H */
263+
#endif /* NEMO_SYSTEMSETTINGS_DEVICEINFO_H_ */

src/src.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ QT -= gui
88
CONFIG += c++11 hide_symbols link_pkgconfig
99
PKGCONFIG += profile mlite5 mce timed-qt5 blkid libcrypto libsailfishkeyprovider connman-qt5 glib-2.0
1010
PKGCONFIG += ssu-sysinfo nemodbus packagekitqt5 libsystemd sailfishusermanager sailfishaccesscontrol
11+
PKGCONFIG += qofono-qt5
1112

1213
system($$[QT_INSTALL_BINS]/qdbusxml2cpp -p mceiface.h:mceiface.cpp mce.xml)
1314

0 commit comments

Comments
 (0)