blob: af072ac8218a64f6783c770c6bc9b33ec59a1cfb [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{
45 connectAccount(LRCInstance::getCurrAccId());
46}
47
48void
49AccountAdapter::accountChanged(int index)
50{
51 auto accountList = LRCInstance::accountModel().getAccountList();
52 if (accountList.size() > index)
53 setSelectedAccount(accountList.at(index), index);
54}
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
241AccountAdapter::startPreviewing(bool force)
242{
243 LRCInstance::renderer()->startPreviewing(force);
244}
245
246void
247AccountAdapter::stopPreviewing()
248{
249 if (!LRCInstance::hasVideoCall() && LRCInstance::renderer()->isPreviewing()) {
250 LRCInstance::renderer()->stopPreviewing();
251 }
252}
253
254bool
255AccountAdapter::hasVideoCall()
256{
257 return LRCInstance::hasVideoCall();
258}
259
260bool
261AccountAdapter::isPreviewing()
262{
263 return LRCInstance::renderer()->isPreviewing();
264}
265
266RenderManager *
267AccountAdapter::getRenderManager()
268{
269 return LRCInstance::renderer();
270}
271
272void
273AccountAdapter::setCurrAccDisplayName(QString text)
274{
275 LRCInstance::setCurrAccDisplayName(text);
276}
277
278void
279AccountAdapter::setSelectedAccountId(QString accountId)
280{
281 LRCInstance::setSelectedAccountId(accountId);
282}
283
284void
285AccountAdapter::setSelectedConvId(QString accountId)
286{
287 LRCInstance::setSelectedConvId(accountId);
288}
289
290bool
291AccountAdapter::hasPassword()
292{
293 auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
294 return confProps.archiveHasPassword;
295}
296
297void
298AccountAdapter::setArchiveHasPassword(bool isHavePassword)
299{
300 auto confProps = LRCInstance::accountModel().getAccountConfig(LRCInstance::getCurrAccId());
301 confProps.archiveHasPassword = isHavePassword;
302 LRCInstance::accountModel().setAccountConfig(LRCInstance::getCurrAccId(), confProps);
303}
304bool
305AccountAdapter::exportToFile(const QString &accountId,
306 const QString &path,
307 const QString &password) const
308{
309 return LRCInstance::accountModel().exportToFile(accountId, path, password);
310}
311
312void
313AccountAdapter::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
322lrc::api::NewAccountModel *
323AccountAdapter::accoundModel()
324{
325 return &(LRCInstance::accountModel());
326}
327
328lrc::api::AVModel *
329AccountAdapter::avModel()
330{
331 return &(LRCInstance::avModel());
332}
333
334lrc::api::DataTransferModel *
335AccountAdapter::dataTransferModel()
336{
337 return &(LRCInstance::dataTransferModel());
338}
339
340void
341AccountAdapter::settingsNeverShowAgain(bool checked)
342{
343 QSettings settings("jami.net", "Jami");
344 settings.setValue(SettingsKey::neverShowMeAgain, checked);
345}
346
347void
348AccountAdapter::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
357void
358AccountAdapter::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
369void
370AccountAdapter::backToWelcomePage(int index)
371{
372 deselectConversation();
373 QMetaObject::invokeMethod(qmlObj_, "backToWelcomePage", Q_ARG(QVariant, index));
374}
375
376void
377AccountAdapter::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
393void
394AccountAdapter::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}