From b138822c062077431d8fc6a8cba6b02eeb02772c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Lepp=C3=A4nen?= Date: Thu, 26 Mar 2020 15:58:24 +0200 Subject: [PATCH] [nemo-systemsettings] Add setCurrentUser to UserModel. Contributes to JB#47825 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows to logout and login to another user session using usermanager. Signed-off-by: Tomi Leppänen --- rpm/nemo-qml-plugin-systemsettings.spec | 2 +- src/usermodel.cpp | 68 ++++++++++++++++++++++--- src/usermodel.h | 13 +++-- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/rpm/nemo-qml-plugin-systemsettings.spec b/rpm/nemo-qml-plugin-systemsettings.spec index 15b0ecc..1c4a583 100644 --- a/rpm/nemo-qml-plugin-systemsettings.spec +++ b/rpm/nemo-qml-plugin-systemsettings.spec @@ -12,7 +12,7 @@ Requires: connman Requires: mce >= 1.83.0 Requires: libsailfishkeyprovider >= 0.0.14 Requires: connman-qt5 >= 1.2.21 -Requires: user-managerd +Requires: user-managerd >= 0.3.0 Requires(post): coreutils BuildRequires: pkgconfig(Qt5Qml) BuildRequires: pkgconfig(Qt5SystemInfo) diff --git a/src/usermodel.cpp b/src/usermodel.cpp index 1838d0b..b5a9727 100644 --- a/src/usermodel.cpp +++ b/src/usermodel.cpp @@ -232,6 +232,22 @@ void UserModel::removeUser(int row) this, std::bind(&UserModel::userRemoveFinished, this, std::placeholders::_1, row)); } +void UserModel::setCurrentUser(int row) +{ + if (row < 0 || row >= m_users.count()) + return; + + auto user = m_users.at(row); + if (!user.isValid()) + return; + + createInterface(); + auto call = m_dBusInterface->asyncCall(QStringLiteral("setCurrentUser"), (uint)user.uid()); + auto *watcher = new QDBusPendingCallWatcher(call, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, std::bind(&UserModel::setCurrentUserFinished, this, std::placeholders::_1, row)); +} + void UserModel::reset(int row) { if (row < 0 || row >= m_users.count()) @@ -247,7 +263,7 @@ UserInfo * UserModel::getCurrentUser() const return new UserInfo(); } -void UserModel::userAdded(const SailfishUserManagerEntry &entry) +void UserModel::onUserAdded(const SailfishUserManagerEntry &entry) { if (m_uidsToRows.contains(entry.uid)) return; @@ -263,7 +279,7 @@ void UserModel::userAdded(const SailfishUserManagerEntry &entry) } } -void UserModel::userModified(uint uid, const QString &newName) +void UserModel::onUserModified(uint uid, const QString &newName) { if (!m_uidsToRows.contains(uid)) return; @@ -277,7 +293,7 @@ void UserModel::userModified(uint uid, const QString &newName) } } -void UserModel::userRemoved(uint uid) +void UserModel::onUserRemoved(uint uid) { if (!m_uidsToRows.contains(uid)) return; @@ -289,6 +305,30 @@ void UserModel::userRemoved(uint uid) endRemoveRows(); } +void UserModel::onCurrentUserChanged(uint uid) +{ + UserInfo *previous = getCurrentUser(); + if (previous) { + if (previous->updateCurrent()) { + auto idx = index(m_uidsToRows[previous->uid()], 0); + emit dataChanged(idx, idx, QVector() << CurrentRole); + } + delete previous; + } + if (m_uidsToRows.contains(uid) && m_users[m_uidsToRows[uid]].updateCurrent()) { + auto idx = index(m_uidsToRows[uid], 0); + emit dataChanged(idx, idx, QVector() << CurrentRole); + } +} + +void UserModel::onCurrentUserChangeFailed(uint uid) +{ + if (m_uidsToRows.contains(uid)) { + int row = m_uidsToRows[uid]; + emit setCurrentUserFailed(row, m_users[row].name()); + } +} + void UserModel::userAddFinished(QDBusPendingCallWatcher *call, int row) { QDBusPendingReply reply = *call; @@ -297,7 +337,7 @@ void UserModel::userAddFinished(QDBusPendingCallWatcher *call, int row) qWarning() << "Adding user with usermanager failed:" << reply.error(); } else { uint uid = reply.value(); - // Check that this was not just added to the list by userAdded + // Check that this was not just added to the list by onUserAdded if (!m_uidsToRows.contains(uid)) { beginInsertRows(QModelIndex(), row, row); m_users.insert(row, UserInfo(uid)); @@ -331,6 +371,16 @@ void UserModel::userRemoveFinished(QDBusPendingCallWatcher *call, int row) call->deleteLater(); } +void UserModel::setCurrentUserFinished(QDBusPendingCallWatcher *call, int row) +{ + QDBusPendingReply reply = *call; + if (reply.isError()) { + emit setCurrentUserFailed(row, m_users.at(row).name()); + qWarning() << "Switching user with usermanager failed:" << reply.error(); + } // else user switching was initiated successfully + call->deleteLater(); +} + void UserModel::createInterface() { if (!m_dBusInterface) { @@ -338,11 +388,15 @@ void UserModel::createInterface() m_dBusInterface = new QDBusInterface(UserManagerService, UserManagerPath, UserManagerInterface, QDBusConnection::systemBus(), this); connect(m_dBusInterface, SIGNAL(userAdded(const SailfishUserManagerEntry &)), - this, SLOT(userAdded(const SailfishUserManagerEntry &)), Qt::QueuedConnection); + this, SLOT(onUserAdded(const SailfishUserManagerEntry &)), Qt::QueuedConnection); connect(m_dBusInterface, SIGNAL(userModified(uint, const QString &)), - this, SLOT(userModified(uint, const QString &))); + this, SLOT(onUserModified(uint, const QString &))); connect(m_dBusInterface, SIGNAL(userRemoved(uint)), - this, SLOT(userRemoved(uint))); + this, SLOT(onUserRemoved(uint))); + connect(m_dBusInterface, SIGNAL(currentUserChanged(uint)), + this, SLOT(onCurrentUserChanged(uint))); + connect(m_dBusInterface, SIGNAL(currentUserChangeFailed(uint)), + this, SLOT(onCurrentUserChangeFailed(uint))); } } diff --git a/src/usermodel.h b/src/usermodel.h index d6604c7..54112a8 100644 --- a/src/usermodel.h +++ b/src/usermodel.h @@ -81,6 +81,7 @@ class SYSTEMSETTINGS_EXPORT UserModel: public QAbstractListModel Q_INVOKABLE void createUser(); Q_INVOKABLE void removeUser(int row); Q_INVOKABLE void reset(int row); + Q_INVOKABLE void setCurrentUser(int row); Q_INVOKABLE UserInfo * getCurrentUser() const; signals: @@ -88,14 +89,20 @@ class SYSTEMSETTINGS_EXPORT UserModel: public QAbstractListModel void userAddFailed(); void userModifyFailed(int row, const QString &name); void userRemoveFailed(int row, const QString &name); + void setCurrentUserFailed(int row, const QString &name); private slots: - void userAdded(const SailfishUserManagerEntry &entry); - void userModified(uint uid, const QString &newName); - void userRemoved(uint uid); + void onUserAdded(const SailfishUserManagerEntry &entry); + void onUserModified(uint uid, const QString &newName); + void onUserRemoved(uint uid); + void onCurrentUserChanged(uint uid); + void onCurrentUserChangeFailed(uint uid); + void userAddFinished(QDBusPendingCallWatcher *call, int row); void userModifyFinished(QDBusPendingCallWatcher *call, int row); void userRemoveFinished(QDBusPendingCallWatcher *call, int row); + void setCurrentUserFinished(QDBusPendingCallWatcher *call, int row); + void createInterface(); void destroyInterface();