Sébastien Blin | 1f91576 | 2020-08-03 13:27:42 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2020 by Savoir-faire Linux |
| 3 | * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com> |
| 4 | * Author: Anthony L�onard <anthony.leonard@savoirfairelinux.com |
| 5 | * Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com> |
| 6 | * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> |
| 7 | * Author: Isa Nanic <isa.nanic@savoirfairelinux.com> |
| 8 | * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> |
| 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License as published by |
| 12 | * the Free Software Foundation; either version 3 of the License, or |
| 13 | * (at your option) any later version. |
| 14 | * |
| 15 | * This program is distributed in the hope that it will be useful, |
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | * GNU General Public License for more details. |
| 19 | * |
| 20 | * You should have received a copy of the GNU General Public License |
| 21 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 22 | */ |
| 23 | |
| 24 | #include "accountadapter.h" |
| 25 | |
| 26 | #undef REGISTERED |
| 27 | #include "../daemon/src/dring/account_const.h" |
| 28 | |
| 29 | AccountAdapter::AccountAdapter(QObject *parent) |
| 30 | : QmlAdapterBase(parent) |
| 31 | {} |
| 32 | |
| 33 | AccountAdapter::~AccountAdapter() {} |
| 34 | |
| 35 | AccountAdapter & |
| 36 | AccountAdapter::instance() |
| 37 | { |
| 38 | static auto instance = new AccountAdapter; |
| 39 | return *instance; |
| 40 | } |
| 41 | |
| 42 | void |
| 43 | AccountAdapter::initQmlObject() |
| 44 | { |
| 45 | connectAccount(LRCInstance::getCurrAccId()); |
| 46 | } |
| 47 | |
| 48 | void |
| 49 | AccountAdapter::accountChanged(int index) |
| 50 | { |
| 51 | auto accountList = LRCInstance::accountModel().getAccountList(); |
| 52 | if (accountList.size() > index) |
| 53 | setSelectedAccount(accountList.at(index), index); |
| 54 | } |
| 55 | |
| 56 | void |
| 57 | AccountAdapter::connectFailure() |
| 58 | { |
| 59 | Utils::oneShotConnect(&LRCInstance::accountModel(), |
| 60 | &lrc::api::NewAccountModel::accountRemoved, |
| 61 | [this](const QString &accountId) { |
| 62 | Q_UNUSED(accountId); |
| 63 | |
| 64 | emit reportFailure(); |
| 65 | }); |
| 66 | Utils::oneShotConnect(&LRCInstance::accountModel(), |
| 67 | &lrc::api::NewAccountModel::invalidAccountDetected, |
| 68 | [this](const QString &accountId) { |
| 69 | Q_UNUSED(accountId); |
| 70 | |
| 71 | emit reportFailure(); |
| 72 | }); |
| 73 | } |
| 74 | |
| 75 | void |
| 76 | AccountAdapter::createJamiAccount(QString registeredName, |
| 77 | const QVariantMap &settings, |
| 78 | QString photoBoothImgBase64, |
| 79 | bool isCreating) |
| 80 | { |
| 81 | Utils::oneShotConnect( |
| 82 | &LRCInstance::accountModel(), |
| 83 | &lrc::api::NewAccountModel::accountAdded, |
| 84 | [this, registeredName, settings, isCreating, photoBoothImgBase64](const QString &accountId) { |
| 85 | QSettings qSettings("jami.net", "Jami"); |
| 86 | if (not qSettings.contains(SettingsKey::neverShowMeAgain)) { |
| 87 | qSettings.setValue(SettingsKey::neverShowMeAgain, false); |
| 88 | } |
| 89 | auto showBackup = isCreating && !settings.value(SettingsKey::neverShowMeAgain).toBool(); |
| 90 | |
| 91 | if (!registeredName.isEmpty()) { |
| 92 | Utils::oneShotConnect(&LRCInstance::accountModel(), |
| 93 | &lrc::api::NewAccountModel::nameRegistrationEnded, |
| 94 | [this, showBackup](const QString &accountId) { |
| 95 | emit accountAdded(showBackup, |
| 96 | LRCInstance::accountModel() |
| 97 | .getAccountList() |
| 98 | .indexOf(accountId)); |
| 99 | }); |
| 100 | LRCInstance::accountModel().registerName(accountId, |
| 101 | settings["password"].toString(), |
| 102 | registeredName); |
| 103 | } else { |
| 104 | emit accountAdded(showBackup, |
| 105 | LRCInstance::accountModel().getAccountList().indexOf(accountId)); |
| 106 | } |
| 107 | // set up avatar pixmap from photobooth |
| 108 | QImage avatarImg; |
| 109 | const bool ret = avatarImg.loadFromData( |
| 110 | QByteArray::fromBase64(photoBoothImgBase64.toLatin1())); |
| 111 | if (!ret) { |
| 112 | qDebug() << "JAMI account creation BASE64 image loading failed"; |
| 113 | } else { |
| 114 | LRCInstance::setAvatarForAccount(QPixmap::fromImage(avatarImg), accountId); |
| 115 | } |
| 116 | }); |
| 117 | |
| 118 | connectFailure(); |
| 119 | |
| 120 | QtConcurrent::run([this, settings] { |
| 121 | QMap<QString, QString> additionalAccountConfig; |
| 122 | additionalAccountConfig.insert(DRing::Account::ConfProperties::Ringtone::PATH, |
| 123 | Utils::GetRingtonePath()); |
| 124 | |
| 125 | LRCInstance::accountModel().createNewAccount(lrc::api::profile::Type::RING, |
| 126 | settings["alias"].toString(), |
| 127 | settings["archivePath"].toString(), |
| 128 | settings["password"].toString(), |
| 129 | settings["archivePin"].toString(), |
| 130 | "", |
| 131 | additionalAccountConfig); |
| 132 | }); |
| 133 | } |
| 134 | |
| 135 | void |
| 136 | AccountAdapter::createSIPAccount(const QVariantMap &settings, QString photoBoothImgBase64) |
| 137 | { |
| 138 | Utils::oneShotConnect(&LRCInstance::accountModel(), |
| 139 | &lrc::api::NewAccountModel::accountAdded, |
| 140 | [this, settings, photoBoothImgBase64](const QString &accountId) { |
| 141 | auto confProps = LRCInstance::accountModel().getAccountConfig( |
| 142 | accountId); |
| 143 | // set SIP details |
| 144 | confProps.hostname = settings["hostname"].toString(); |
| 145 | confProps.username = settings["username"].toString(); |
| 146 | confProps.password = settings["password"].toString(); |
| 147 | confProps.proxyServer = settings["proxy"].toString(); |
| 148 | LRCInstance::accountModel().setAccountConfig(accountId, confProps); |
| 149 | |
| 150 | // set up photobooth avatar to SIP avatar |
| 151 | QImage avatarImg; |
| 152 | const bool ret = avatarImg.loadFromData( |
| 153 | QByteArray::fromBase64(photoBoothImgBase64.toLatin1())); |
| 154 | if (!ret) { |
| 155 | qDebug() << "SIP account creation BASE64 image loading failed"; |
| 156 | } else { |
| 157 | LRCInstance::setAvatarForAccount(QPixmap::fromImage(avatarImg), |
| 158 | accountId); |
| 159 | } |
| 160 | |
| 161 | emit accountAdded(false, |
| 162 | LRCInstance::accountModel().getAccountList().indexOf( |
| 163 | accountId)); |
| 164 | }); |
| 165 | |
| 166 | connectFailure(); |
| 167 | |
| 168 | QtConcurrent::run([this, settings] { |
| 169 | QMap<QString, QString> additionalAccountConfig; |
| 170 | additionalAccountConfig.insert(DRing::Account::ConfProperties::Ringtone::PATH, |
| 171 | Utils::GetRingtonePath()); |
| 172 | |
| 173 | LRCInstance::accountModel().createNewAccount(lrc::api::profile::Type::SIP, |
| 174 | settings["alias"].toString(), |
| 175 | settings["archivePath"].toString(), |
| 176 | "", |
| 177 | "", |
| 178 | settings["username"].toString(), |
| 179 | additionalAccountConfig); |
| 180 | QThread::sleep(2); |
| 181 | emit LRCInstance::instance().accountListChanged(); |
| 182 | }); |
| 183 | } |
| 184 | |
| 185 | void |
| 186 | AccountAdapter::createJAMSAccount(const QVariantMap &settings) |
| 187 | { |
| 188 | Utils::oneShotConnect(&LRCInstance::accountModel(), |
| 189 | &lrc::api::NewAccountModel::accountAdded, |
| 190 | [this](const QString &accountId) { |
| 191 | Q_UNUSED(accountId) |
| 192 | if (!LRCInstance::accountModel().getAccountList().size()) |
| 193 | return; |
| 194 | emit accountAdded(false, |
| 195 | LRCInstance::accountModel().getAccountList().indexOf( |
| 196 | accountId)); |
| 197 | emit LRCInstance::instance().accountListChanged(); |
| 198 | }); |
| 199 | |
| 200 | connectFailure(); |
| 201 | |
| 202 | QtConcurrent::run([this, settings] { |
| 203 | QMap<QString, QString> additionalAccountConfig; |
| 204 | additionalAccountConfig.insert(DRing::Account::ConfProperties::Ringtone::PATH, |
| 205 | Utils::GetRingtonePath()); |
| 206 | |
| 207 | LRCInstance::accountModel().connectToAccountManager(settings["username"].toString(), |
| 208 | settings["password"].toString(), |
| 209 | settings["manager"].toString(), |
| 210 | additionalAccountConfig); |
| 211 | }); |
| 212 | } |
| 213 | |
| 214 | void |
| 215 | AccountAdapter::deleteCurrentAccount() |
| 216 | { |
| 217 | LRCInstance::accountModel().removeAccount(LRCInstance::getCurrAccId()); |
| 218 | } |
| 219 | |
| 220 | bool |
| 221 | AccountAdapter::savePassword(const QString accountId, |
| 222 | const QString oldPassword, |
| 223 | const QString newPassword) |
| 224 | { |
| 225 | return LRCInstance::accountModel().changeAccountPassword(accountId, oldPassword, newPassword); |
| 226 | } |
| 227 | |
| 228 | void |
| 229 | AccountAdapter::startAudioMeter(bool async) |
| 230 | { |
| 231 | LRCInstance::startAudioMeter(async); |
| 232 | } |
| 233 | |
| 234 | void |
| 235 | AccountAdapter::stopAudioMeter(bool async) |
| 236 | { |
| 237 | LRCInstance::stopAudioMeter(async); |
| 238 | } |
| 239 | |
| 240 | void |
| 241 | AccountAdapter::startPreviewing(bool force) |
| 242 | { |
| 243 | LRCInstance::renderer()->startPreviewing(force); |
| 244 | } |
| 245 | |
| 246 | void |
| 247 | AccountAdapter::stopPreviewing() |
| 248 | { |
| 249 | if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) { |
| 250 | LRCInstance::renderer()->stopPreviewing(); |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | bool |
| 255 | AccountAdapter::hasVideoCall() |
| 256 | { |
| 257 | return LRCInstance::hasVideoCall(); |
| 258 | } |
| 259 | |
| 260 | bool |
| 261 | AccountAdapter::isPreviewing() |
| 262 | { |
| 263 | return LRCInstance::renderer()->isPreviewing(); |
| 264 | } |
| 265 | |
| 266 | RenderManager * |
| 267 | AccountAdapter::getRenderManager() |
| 268 | { |
| 269 | return LRCInstance::renderer(); |
| 270 | } |
| 271 | |
| 272 | void |
| 273 | AccountAdapter::setCurrAccDisplayName(QString text) |
| 274 | { |
| 275 | LRCInstance::setCurrAccDisplayName(text); |
| 276 | } |
| 277 | |
| 278 | void |
| 279 | AccountAdapter::setSelectedAccountId(QString accountId) |
| 280 | { |
| 281 | LRCInstance::setSelectedAccountId(accountId); |
| 282 | } |
| 283 | |
| 284 | void |
| 285 | AccountAdapter::setSelectedConvId(QString accountId) |
| 286 | { |
| 287 | LRCInstance::setSelectedConvId(accountId); |
| 288 | } |
| 289 | |
| 290 | bool |
| 291 | AccountAdapter::hasPassword() |
| 292 | { |
| 293 | auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId()); |
| 294 | return confProps.archiveHasPassword; |
| 295 | } |
| 296 | |
| 297 | void |
| 298 | AccountAdapter::setArchiveHasPassword(bool isHavePassword) |
| 299 | { |
| 300 | auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId()); |
| 301 | confProps.archiveHasPassword = isHavePassword; |
| 302 | LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps); |
| 303 | } |
| 304 | bool |
| 305 | AccountAdapter::exportToFile(const QString &accountId, |
| 306 | const QString &path, |
| 307 | const QString &password) const |
| 308 | { |
| 309 | return LRCInstance::accountModel().exportToFile(accountId, path, password); |
| 310 | } |
| 311 | |
| 312 | void |
| 313 | AccountAdapter::setArchivePasswordAsync(const QString &accountID, const QString &password) |
| 314 | { |
| 315 | QtConcurrent::run([this, accountID, password] { |
| 316 | auto config = LRCInstance::accountModel().getAccountConfig(accountID); |
| 317 | config.archivePassword = password; |
| 318 | LRCInstance::accountModel().setAccountConfig(accountID, config); |
| 319 | }); |
| 320 | } |
| 321 | |
| 322 | lrc::api::NewAccountModel * |
| 323 | AccountAdapter::accoundModel() |
| 324 | { |
| 325 | return &(LRCInstance::accountModel()); |
| 326 | } |
| 327 | |
| 328 | lrc::api::AVModel * |
| 329 | AccountAdapter::avModel() |
| 330 | { |
| 331 | return &(LRCInstance::avModel()); |
| 332 | } |
| 333 | |
| 334 | lrc::api::DataTransferModel * |
| 335 | AccountAdapter::dataTransferModel() |
| 336 | { |
| 337 | return &(LRCInstance::dataTransferModel()); |
| 338 | } |
| 339 | |
| 340 | void |
| 341 | AccountAdapter::settingsNeverShowAgain(bool checked) |
| 342 | { |
| 343 | QSettings settings("jami.net", "Jami"); |
| 344 | settings.setValue(SettingsKey::neverShowMeAgain, checked); |
| 345 | } |
| 346 | |
| 347 | void |
| 348 | AccountAdapter::passwordSetStatusMessageBox(bool success, QString title, QString infoToDisplay) |
| 349 | { |
| 350 | if (success) { |
| 351 | QMessageBox::information(0, title, infoToDisplay); |
| 352 | } else { |
| 353 | QMessageBox::critical(0, title, infoToDisplay); |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | void |
| 358 | AccountAdapter::setSelectedAccount(const QString &accountId, int index) |
| 359 | { |
| 360 | LRCInstance::setSelectedAccountId(accountId); |
| 361 | |
| 362 | backToWelcomePage(index); |
| 363 | |
| 364 | QMetaObject::invokeMethod(qmlObj_, "updateSmartList", Q_ARG(QVariant, accountId)); |
| 365 | connectAccount(accountId); |
| 366 | emit accountSignalsReconnect(accountId); |
| 367 | } |
| 368 | |
| 369 | void |
| 370 | AccountAdapter::backToWelcomePage(int index) |
| 371 | { |
| 372 | deselectConversation(); |
| 373 | QMetaObject::invokeMethod(qmlObj_, "backToWelcomePage", Q_ARG(QVariant, index)); |
| 374 | } |
| 375 | |
| 376 | void |
| 377 | AccountAdapter::deselectConversation() |
| 378 | { |
| 379 | if (LRCInstance::getCurrentConvUid().isEmpty()) { |
| 380 | return; |
| 381 | } |
| 382 | |
| 383 | auto currentConversationModel = LRCInstance::getCurrentConversationModel(); |
| 384 | |
| 385 | if (currentConversationModel == nullptr) { |
| 386 | return; |
| 387 | } |
| 388 | |
| 389 | currentConversationModel->selectConversation(""); |
| 390 | LRCInstance::setSelectedConvId(); |
| 391 | } |
| 392 | |
| 393 | void |
| 394 | AccountAdapter::connectAccount(const QString &accountId) |
| 395 | { |
| 396 | try { |
| 397 | auto &accInfo = LRCInstance::accountModel().getAccountInfo(accountId); |
| 398 | |
| 399 | QObject::disconnect(accountStatusChangedConnection_); |
| 400 | QObject::disconnect(contactAddedConnection_); |
| 401 | |
| 402 | accountStatusChangedConnection_ |
| 403 | = QObject::connect(accInfo.accountModel, |
| 404 | &lrc::api::NewAccountModel::accountStatusChanged, |
| 405 | [this] { emit accountStatusChanged(); }); |
| 406 | |
| 407 | contactAddedConnection_ |
| 408 | = QObject::connect(accInfo.contactModel.get(), |
| 409 | &lrc::api::ContactModel::contactAdded, |
| 410 | [this, accountId](const QString &contactUri) { |
| 411 | auto &accInfo = LRCInstance::accountModel().getAccountInfo( |
| 412 | accountId); |
| 413 | auto conversation = LRCInstance::getCurrentConversation(); |
| 414 | if (conversation.uid.isEmpty()) { |
| 415 | return; |
| 416 | } |
| 417 | if (contactUri |
| 418 | == accInfo.contactModel |
| 419 | ->getContact(conversation.participants.at(0)) |
| 420 | .profileInfo.uri) { |
| 421 | /* |
| 422 | * Update conversation. |
| 423 | */ |
| 424 | emit updateConversationForAddedContact(); |
| 425 | } |
| 426 | }); |
| 427 | QObject::disconnect(addedToConferenceConnection_); |
| 428 | addedToConferenceConnection_ |
| 429 | = QObject::connect(accInfo.callModel.get(), |
| 430 | &NewCallModel::callAddedToConference, |
| 431 | [this](const QString &callId, const QString &confId) { |
| 432 | Q_UNUSED(callId); |
| 433 | LRCInstance::renderer()->addDistantRenderer(confId); |
| 434 | }); |
| 435 | } catch (...) { |
| 436 | qWarning() << "Couldn't get account: " << accountId; |
| 437 | } |
| 438 | } |