blob: 2358ece9a14708ba0ba9bb94029a47ff024a694c [file] [log] [blame]
Sébastien Blin1f915762020-08-03 13:27:42 -04001/*
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
29AccountAdapter::AccountAdapter(QObject *parent)
30 : QmlAdapterBase(parent)
31{}
32
33AccountAdapter::~AccountAdapter() {}
34
35AccountAdapter &
36AccountAdapter::instance()
37{
38 static auto instance = new AccountAdapter;
39 return *instance;
40}
41
42void
43AccountAdapter::initQmlObject()
44{
ababi69f5dfc2020-08-25 15:07:57 +020045 setSelectedAccount(LRCInstance::getCurrAccId());
Sébastien Blin1f915762020-08-03 13:27:42 -040046}
47
48void
49AccountAdapter::accountChanged(int index)
50{
51 auto accountList = LRCInstance::accountModel().getAccountList();
52 if (accountList.size() > index)
ababi69f5dfc2020-08-25 15:07:57 +020053 setSelectedAccount(accountList.at(index));
Sébastien Blin1f915762020-08-03 13:27:42 -040054}
55
56void
57AccountAdapter::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
75void
76AccountAdapter::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
135void
136AccountAdapter::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
185void
186AccountAdapter::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
214void
215AccountAdapter::deleteCurrentAccount()
216{
217 LRCInstance::accountModel().removeAccount(LRCInstance::getCurrAccId());
218}
219
220bool
221AccountAdapter::savePassword(const QString accountId,
222 const QString oldPassword,
223 const QString newPassword)
224{
225 return LRCInstance::accountModel().changeAccountPassword(accountId, oldPassword, newPassword);
226}
227
228void
229AccountAdapter::startAudioMeter(bool async)
230{
231 LRCInstance::startAudioMeter(async);
232}
233
234void
235AccountAdapter::stopAudioMeter(bool async)
236{
237 LRCInstance::stopAudioMeter(async);
238}
239
240void
Yang Wangc2ea0b12020-08-18 13:24:37 -0400241AccountAdapter::startPreviewing(bool force, bool async)
Sébastien Blin1f915762020-08-03 13:27:42 -0400242{
Yang Wangc2ea0b12020-08-18 13:24:37 -0400243 LRCInstance::renderer()->startPreviewing(force, async);
Sébastien Blin1f915762020-08-03 13:27:42 -0400244}
245
246void
Yang Wangc2ea0b12020-08-18 13:24:37 -0400247AccountAdapter::stopPreviewing(bool async)
Sébastien Blin1f915762020-08-03 13:27:42 -0400248{
249 if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) {
Yang Wangc2ea0b12020-08-18 13:24:37 -0400250 LRCInstance::renderer()->stopPreviewing(async);
Sébastien Blin1f915762020-08-03 13:27:42 -0400251 }
252}
253
254bool
255AccountAdapter::hasVideoCall()
256{
257 return LRCInstance::hasVideoCall();
258}
259
260bool
261AccountAdapter::isPreviewing()
262{
263 return LRCInstance::renderer()->isPreviewing();
264}
265
Sébastien Blin1f915762020-08-03 13:27:42 -0400266void
267AccountAdapter::setCurrAccDisplayName(QString text)
268{
269 LRCInstance::setCurrAccDisplayName(text);
270}
271
272void
273AccountAdapter::setSelectedAccountId(QString accountId)
274{
275 LRCInstance::setSelectedAccountId(accountId);
276}
277
278void
279AccountAdapter::setSelectedConvId(QString accountId)
280{
281 LRCInstance::setSelectedConvId(accountId);
282}
283
284bool
285AccountAdapter::hasPassword()
286{
287 auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
288 return confProps.archiveHasPassword;
289}
290
291void
292AccountAdapter::setArchiveHasPassword(bool isHavePassword)
293{
294 auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
295 confProps.archiveHasPassword = isHavePassword;
296 LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
297}
298bool
299AccountAdapter::exportToFile(const QString &accountId,
300 const QString &path,
301 const QString &password) const
302{
303 return LRCInstance::accountModel().exportToFile(accountId, path, password);
304}
305
306void
307AccountAdapter::setArchivePasswordAsync(const QString &accountID, const QString &password)
308{
309 QtConcurrent::run([this, accountID, password] {
310 auto config = LRCInstance::accountModel().getAccountConfig(accountID);
311 config.archivePassword = password;
312 LRCInstance::accountModel().setAccountConfig(accountID, config);
313 });
314}
315
Sébastien Blin1f915762020-08-03 13:27:42 -0400316void
317AccountAdapter::settingsNeverShowAgain(bool checked)
318{
319 QSettings settings("jami.net", "Jami");
320 settings.setValue(SettingsKey::neverShowMeAgain, checked);
321}
322
323void
324AccountAdapter::passwordSetStatusMessageBox(bool success, QString title, QString infoToDisplay)
325{
326 if (success) {
327 QMessageBox::information(0, title, infoToDisplay);
328 } else {
329 QMessageBox::critical(0, title, infoToDisplay);
330 }
331}
332
333void
ababi69f5dfc2020-08-25 15:07:57 +0200334AccountAdapter::setSelectedAccount(const QString &accountId)
Sébastien Blin1f915762020-08-03 13:27:42 -0400335{
336 LRCInstance::setSelectedAccountId(accountId);
337
Sébastien Blin1f915762020-08-03 13:27:42 -0400338 connectAccount(accountId);
339 emit accountSignalsReconnect(accountId);
Ming Rui Zhangb07f7af2020-08-27 16:46:22 -0400340
341 backToWelcomePage();
Sébastien Blin1f915762020-08-03 13:27:42 -0400342}
343
344void
ababi69f5dfc2020-08-25 15:07:57 +0200345AccountAdapter::backToWelcomePage()
Sébastien Blin1f915762020-08-03 13:27:42 -0400346{
347 deselectConversation();
ababi69f5dfc2020-08-25 15:07:57 +0200348 QMetaObject::invokeMethod(qmlObj_, "backToWelcomePage");
Sébastien Blin1f915762020-08-03 13:27:42 -0400349}
350
351void
352AccountAdapter::deselectConversation()
353{
354 if (LRCInstance::getCurrentConvUid().isEmpty()) {
355 return;
356 }
357
358 auto currentConversationModel = LRCInstance::getCurrentConversationModel();
359
360 if (currentConversationModel == nullptr) {
361 return;
362 }
363
364 currentConversationModel->selectConversation("");
365 LRCInstance::setSelectedConvId();
366}
367
368void
369AccountAdapter::connectAccount(const QString &accountId)
370{
371 try {
372 auto &accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
373
374 QObject::disconnect(accountStatusChangedConnection_);
375 QObject::disconnect(contactAddedConnection_);
376
377 accountStatusChangedConnection_
378 = QObject::connect(accInfo.accountModel,
379 &lrc::api::NewAccountModel::accountStatusChanged,
380 [this] { emit accountStatusChanged(); });
381
382 contactAddedConnection_
383 = QObject::connect(accInfo.contactModel.get(),
384 &lrc::api::ContactModel::contactAdded,
385 [this, accountId](const QString &contactUri) {
386 auto &accInfo = LRCInstance::accountModel().getAccountInfo(
387 accountId);
ababi0b686642020-08-18 17:21:28 +0200388 auto* convModel = LRCInstance::getCurrentConversationModel();
389 const auto conversation = convModel->getConversationForUID(
390 LRCInstance::getCurrentConvUid());
Sébastien Blin1f915762020-08-03 13:27:42 -0400391 if (conversation.uid.isEmpty()) {
392 return;
393 }
394 if (contactUri
395 == accInfo.contactModel
396 ->getContact(conversation.participants.at(0))
397 .profileInfo.uri) {
398 /*
399 * Update conversation.
400 */
401 emit updateConversationForAddedContact();
402 }
403 });
404 QObject::disconnect(addedToConferenceConnection_);
405 addedToConferenceConnection_
406 = QObject::connect(accInfo.callModel.get(),
407 &NewCallModel::callAddedToConference,
408 [this](const QString &callId, const QString &confId) {
409 Q_UNUSED(callId);
410 LRCInstance::renderer()->addDistantRenderer(confId);
411 });
412 } catch (...) {
413 qWarning() << "Couldn't get account: " << accountId;
414 }
415}