diff --git a/.gitlab-ci-files/job-macosx-desktop.yml b/.gitlab-ci-files/job-macosx-desktop.yml
index b4f901143..256101a64 100644
--- a/.gitlab-ci-files/job-macosx-desktop.yml
+++ b/.gitlab-ci-files/job-macosx-desktop.yml
@@ -22,7 +22,7 @@
.job-macosx-desktop:
stage: build
- tags: [ "macosx-xcode11" ]
+ tags: [ "macmini-m1-xcode13" ]
script:
- *build_all_script
variables:
@@ -88,7 +88,7 @@ job-macosx-ninja-novideo:
job-macosx-makefile-package:
stage: package
- tags: [ "macosx-xcode11" ]
+ tags: [ "macmini-m1-xcode13" ]
dependencies: []
only:
variables:
@@ -97,6 +97,7 @@ job-macosx-makefile-package:
- $DEPLOY_MACOSX
variables:
CMAKE_OPTIONS: -DENABLE_APP_PACKAGING=YES -DENABLE_G729=ON -DLINPHONE_SDK_MAKE_RELEASE_FILE_URL=$MAKE_RELEASE_FILE_URL/$MACOSX_PLATFORM/$APP_FOLDER
+ LINPHONESDK_MACOS_ARCHS: "x86_64,arm64"
extends: job-macosx-makefile
script:
- *build_all_script
@@ -109,7 +110,7 @@ job-macosx-makefile-package:
job-macosx-codesigning:
stage: signing
- tags: [ "macosx-xcode11" ]
+ tags: [ "macmini-m1-xcode13" ]
needs:
- job-macosx-makefile-package
only:
@@ -134,7 +135,7 @@ job-macosx-codesigning:
job-macosx-makefile-deploy:
stage: deploy
- tags: [ "macosx-xcode11" ]
+ tags: [ "macmini-m1-xcode13" ]
needs:
- job-macosx-codesigning
only:
@@ -149,7 +150,7 @@ job-macosx-makefile-deploy:
job-macosx-makefile-plugins-deploy:
stage: deploy
- tags: [ "macosx-xcode11" ]
+ tags: [ "macmini-m1-xcode13" ]
needs:
- job-macosx-makefile
only:
diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt
index ec594890e..1d1f410e8 100644
--- a/linphone-app/CMakeLists.txt
+++ b/linphone-app/CMakeLists.txt
@@ -45,7 +45,7 @@ include(CheckCXXCompilerFlag)
set(TARGET_NAME linphone-qt)
set(LINPHONE_QML_DIR "WORK/qml_files/ui")
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS true)
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD 14)
if(UNIX AND NOT APPLE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
@@ -154,6 +154,7 @@ set(SOURCES
src/app/providers/AvatarProvider.cpp
src/app/providers/ImageProvider.cpp
src/app/providers/ExternalImageProvider.cpp
+ src/app/providers/QRCodeProvider.cpp
src/app/providers/ThumbnailProvider.cpp
src/app/proxyModel/ProxyListModel.cpp
src/app/proxyModel/SortFilterProxyModel.cpp
@@ -281,6 +282,7 @@ set(HEADERS
src/app/providers/AvatarProvider.hpp
src/app/providers/ImageProvider.hpp
src/app/providers/ExternalImageProvider.hpp
+ src/app/providers/QRCodeProvider.hpp
src/app/providers/ThumbnailProvider.hpp
src/app/proxyModel/ProxyAbstractListModel.hpp
src/app/proxyModel/ProxyAbstractMapModel.hpp
diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts
index 61eb0937e..f3879c2d2 100644
--- a/linphone-app/assets/languages/da.ts
+++ b/linphone-app/assets/languages/da.ts
@@ -1325,6 +1325,31 @@ Server url ikke konfigureret.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts
index e441e4d0a..1545fc759 100644
--- a/linphone-app/assets/languages/de.ts
+++ b/linphone-app/assets/languages/de.ts
@@ -1325,6 +1325,31 @@ Server URL ist nicht konfiguriert.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index 9f1a8c909..0f4bc20c7 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -1325,6 +1325,31 @@ Server URL not configured.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
Last remote provisioning failed
+
+ generateLabel
+ 'generate' : title button to generate a code.
+ generate
+
+
+ or
+ 'or' : conjunction to choose between options.
+ or
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+ Click on %1 to obtain your remote provisioning QR code
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+ Scan the QR code with your phone
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+ In your app go in assistant - QR code provisioning
+
HistoryView
diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts
index 6fe162165..b6094b842 100644
--- a/linphone-app/assets/languages/es.ts
+++ b/linphone-app/assets/languages/es.ts
@@ -1325,6 +1325,31 @@ URL del servidor no configurada.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts
index e35e0a2eb..5c269161b 100644
--- a/linphone-app/assets/languages/fr_FR.ts
+++ b/linphone-app/assets/languages/fr_FR.ts
@@ -1325,6 +1325,31 @@ URL du serveur non configurée.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
La dernière configuration n'a pas pu être récupérée
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts
index b0f6ce1a6..16359799e 100644
--- a/linphone-app/assets/languages/hu.ts
+++ b/linphone-app/assets/languages/hu.ts
@@ -1315,6 +1315,31 @@ A kiszolgáló URL-je nincs konfigurálva.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
Az utolsó távoli kiépítés nem sikerült
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts
index d919beff8..a8def0c44 100644
--- a/linphone-app/assets/languages/it.ts
+++ b/linphone-app/assets/languages/it.ts
@@ -1325,6 +1325,31 @@ URL del server non configurato.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
L'ultima configurazione remota è fallita
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts
index 588fabbe1..d5f58b6b1 100644
--- a/linphone-app/assets/languages/ja.ts
+++ b/linphone-app/assets/languages/ja.ts
@@ -1315,6 +1315,31 @@
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts
index 509fad401..9ccc1b330 100644
--- a/linphone-app/assets/languages/lt.ts
+++ b/linphone-app/assets/languages/lt.ts
@@ -1335,6 +1335,31 @@ Nesukonfigūruotas serverio url.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts
index b4181348f..6018f8a6f 100644
--- a/linphone-app/assets/languages/pt_BR.ts
+++ b/linphone-app/assets/languages/pt_BR.ts
@@ -1325,6 +1325,31 @@ URL do servidor não configurado.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts
index 31502f90d..ae52dcd2e 100644
--- a/linphone-app/assets/languages/ru.ts
+++ b/linphone-app/assets/languages/ru.ts
@@ -1335,6 +1335,31 @@
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
Последняя удалённая инициализация не удалась
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts
index c55ee3782..52d715ed3 100644
--- a/linphone-app/assets/languages/sv.ts
+++ b/linphone-app/assets/languages/sv.ts
@@ -1325,6 +1325,31 @@ Serverwebbadressen är inte konfigurerad.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts
index 3e893e4be..ea5fabd1b 100644
--- a/linphone-app/assets/languages/tr.ts
+++ b/linphone-app/assets/languages/tr.ts
@@ -1315,6 +1315,31 @@ Sunucu url'si yapılandırılmadı.
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
Son uzaktan ön hazırlık başarısız
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts
index e06428997..e526fd4b0 100644
--- a/linphone-app/assets/languages/uk.ts
+++ b/linphone-app/assets/languages/uk.ts
@@ -1335,6 +1335,31 @@
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts
index 72923d84a..8f14bdb70 100644
--- a/linphone-app/assets/languages/zh_CN.ts
+++ b/linphone-app/assets/languages/zh_CN.ts
@@ -1315,6 +1315,31 @@
'Last remote provisioning failed' : Test to warn the user that the last fetch of remote provisioning has failed.
+
+ generateLabel
+ 'generate' : title button to generate a code.
+
+
+
+ or
+ 'or' : conjunction to choose between options.
+
+
+
+ remoteProvisioningHow
+ 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+
+
+
+ scanQRCode
+ 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+
+
+
+ scanQRCodeWhere
+ 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+
+
HistoryView
diff --git a/linphone-app/assets/linphonerc-factory b/linphone-app/assets/linphonerc-factory
index efe183760..7c89abab3 100644
--- a/linphone-app/assets/linphonerc-factory
+++ b/linphone-app/assets/linphonerc-factory
@@ -13,4 +13,7 @@ chat_messages_aggregation=1
zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_K255_KYB512
[video]
-max_mosaic_size=vga
\ No newline at end of file
+max_mosaic_size=vga
+
+[ui]
+use_qrcode=0
\ No newline at end of file
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index a8f6a5d58..d3d6ddeee 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -512,6 +512,7 @@
ui/views/App/Styles/Main/Assistant/AssistantAbstractViewStyle.qml
ui/views/App/Styles/Main/Assistant/AssistantHomeStyle.qml
ui/views/App/Styles/Main/Assistant/CreateAppSipAccountStyle.qml
+ ui/views/App/Styles/Main/Assistant/FetchRemoteConfigurationStyle.qml
ui/views/App/Styles/Main/AssistantStyle.qml
ui/views/App/Styles/Main/Assistant/UseAppSipAccountStyle.qml
ui/views/App/Styles/Main/ConferencesStyle.qml
diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp
index b6117b793..5d8222e77 100644
--- a/linphone-app/src/app/App.cpp
+++ b/linphone-app/src/app/App.cpp
@@ -42,6 +42,7 @@
#include "providers/AvatarProvider.hpp"
#include "providers/ImageProvider.hpp"
#include "providers/ExternalImageProvider.hpp"
+#include "providers/QRCodeProvider.hpp"
#include "providers/ThumbnailProvider.hpp"
#include "translator/DefaultTranslator.hpp"
#include "utils/Utils.hpp"
@@ -380,6 +381,7 @@ void App::initContentApp () {
mEngine->addImageProvider(AvatarProvider::ProviderId, new AvatarProvider());
mEngine->addImageProvider(ImageProvider::ProviderId, new ImageProvider());
mEngine->addImageProvider(ExternalImageProvider::ProviderId, new ExternalImageProvider());
+ mEngine->addImageProvider(QRCodeProvider::ProviderId, new QRCodeProvider());
mEngine->addImageProvider(ThumbnailProvider::ProviderId, new ThumbnailProvider());
mEngine->rootContext()->setContextProperty("applicationName", APPLICATION_NAME);
diff --git a/linphone-app/src/app/providers/QRCodeProvider.cpp b/linphone-app/src/app/providers/QRCodeProvider.cpp
new file mode 100644
index 000000000..5bd6d6ef5
--- /dev/null
+++ b/linphone-app/src/app/providers/QRCodeProvider.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010-2020 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "app/App.hpp"
+
+#include "QRCodeProvider.hpp"
+#include "components/other/colors/ColorListModel.hpp"
+#include "components/other/colors/ColorModel.hpp"
+#include "components/other/images/ImageListModel.hpp"
+#include "components/other/images/ImageModel.hpp"
+
+#include "utils/Constants.hpp"
+
+// =============================================================================
+
+using namespace std;
+
+const QString QRCodeProvider::ProviderId = "qrcode";
+
+QRCodeProvider::QRCodeProvider () : QQuickImageProvider(
+ QQmlImageProviderBase::Image,
+ QQmlImageProviderBase::ForceAsynchronousImageLoading
+ ) {}
+
+// -----------------------------------------------------------------------------
+
+QImage QRCodeProvider::requestImage (const QString &id, QSize *size, const QSize &requestedSize) {
+ unsigned int w = requestedSize.width()>0?requestedSize.width() : 100;
+ unsigned int h = requestedSize.height()>0 ? requestedSize.height() : 100;
+ auto content = linphone::Factory::get()->createQrcode(id.toStdString(), w, h, 0);
+ if( !content)
+ return QImage();
+ QImage image(w, h, QImage::Format_Indexed8);
+ for (int y = 0;ygetBuffer() + y*w, w);
+ QVector colorTable(256);
+ for(int i=0;i<256;i++)
+ colorTable[i] = qRgb(i,i,i);
+ image.setColorTable(colorTable);
+ *size = image.size();
+ return image;
+}
+
+QPixmap QRCodeProvider::requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) {
+ return QPixmap::fromImage(requestImage(id, size, requestedSize));
+}
diff --git a/linphone-app/src/app/providers/QRCodeProvider.hpp b/linphone-app/src/app/providers/QRCodeProvider.hpp
new file mode 100644
index 000000000..9df57f1b8
--- /dev/null
+++ b/linphone-app/src/app/providers/QRCodeProvider.hpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010-2020 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-desktop
+ * (see https://www.linphone.org).
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef QRCODE_PROVIDER_H_
+#define QRCODE_PROVIDER_H_
+
+#include
+
+// =============================================================================
+
+class QRCodeProvider : public QQuickImageProvider {
+public:
+ QRCodeProvider ();
+
+ QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override;
+ QPixmap requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) override;
+
+ static const QString ProviderId;
+
+};
+
+#endif // AVATAR_PROVIDER_H_
diff --git a/linphone-app/src/components/assistant/AssistantModel.cpp b/linphone-app/src/components/assistant/AssistantModel.cpp
index 884092eec..7717aede3 100644
--- a/linphone-app/src/components/assistant/AssistantModel.cpp
+++ b/linphone-app/src/components/assistant/AssistantModel.cpp
@@ -28,7 +28,10 @@
#include "AssistantModel.hpp"
+#include
+
#include
+#include
// =============================================================================
@@ -148,12 +151,18 @@ private:
AssistantModel::AssistantModel (QObject *parent) : QObject(parent) {
mHandlers = make_shared(this);
-
shared_ptr core = CoreManager::getInstance()->getCore();
+ connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::foundQRCode, this, &AssistantModel::onQRCodeFound);
+ mIsReadingQRCode = false;
mAccountCreator = core->createAccountCreator(
core->getConfig()->getString("assistant", "xmlrpc_url", Constants::DefaultXmlrpcUri)
);
mAccountCreator->addListener(mHandlers);
+ connect(this, &AssistantModel::apiReceived, this, &AssistantModel::onApiReceived);
+}
+
+AssistantModel::~AssistantModel(){
+ setIsReadingQRCode(false);
}
// -----------------------------------------------------------------------------
@@ -269,6 +278,79 @@ bool AssistantModel::addOtherSipAccount (const QVariantMap &map) {
}
return false;
}
+void AssistantModel::createTestAccount(){
+}
+void AssistantModel::generateQRCode(){
+ auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
+ flexiAPIClient
+ ->accountProvision()
+ ->then([this](FlexiAPIClient::Response response){
+ emit newQRCodeReceived(response.json()["provisioning_token"].asCString());
+ })
+ ->error([this](FlexiAPIClient::Response response){
+ emit newQRCodeNotReceived(Utils::coreStringToAppString(response.body), response.code);
+ });
+}
+void AssistantModel::requestQRCode(){
+ auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
+
+ flexiAPIClient
+ ->accountAuthTokenCreate()
+ ->then([this](FlexiAPIClient::Response response) {
+ mToken = response.json()["token"].asCString();
+ emit newQRCodeReceived(mToken);
+ QTimer::singleShot(5000, this, &AssistantModel::checkLinkingAccount);
+ })->error([this](FlexiAPIClient::Response response){
+ qWarning() << response.code << " => " << response.body.c_str();
+ emit newQRCodeNotReceived(Utils::coreStringToAppString(response.body), response.code);
+ });
+}
+
+void AssistantModel::readQRCode(){
+ setIsReadingQRCode(!mIsReadingQRCode);
+}
+void AssistantModel::newQRCodeNotReceivedTest(){
+ emit newQRCodeNotReceived("Cannot generate a provisioning key",0);
+}
+void AssistantModel::checkLinkingAccount(){
+ auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
+ flexiAPIClient
+ ->accountApiKeyFromAuthTokenGenerate(mToken.toStdString())
+ ->then([this](FlexiAPIClient::Response response)mutable{
+ emit apiReceived(Utils::coreStringToAppString(response.json()["api_key"].asCString()));
+ })->error([this](FlexiAPIClient::Response){
+ QTimer::singleShot(5000, this, &AssistantModel::checkLinkingAccount);
+ });
+}
+
+void AssistantModel::onApiReceived(QString apiKey){
+ auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
+ flexiAPIClient->setApiKey(Utils::appStringToCoreString(apiKey).c_str())
+ ->accountProvision()
+ ->then([this](FlexiAPIClient::Response response){
+ emit provisioningTokenReceived(response.json()["provisioning_token"].asCString());
+ })->error([this](FlexiAPIClient::Response response){
+ //it provisioningTokenReceived("token");
+ emit this->newQRCodeNotReceived("Cannot generate a provisioning key"+(response.body.empty() ? "" : " : " +Utils::coreStringToAppString(response.body)), response.code);
+ });
+}
+void AssistantModel::onQRCodeFound(const std::string & result){
+ setIsReadingQRCode(false);
+ emit qRCodeFound(Utils::coreStringToAppString(result));
+}
+
+void AssistantModel::attachAccount(const QString& token){
+ auto flexiAPIClient = make_shared(CoreManager::getInstance()->getCore()->cPtr());
+ flexiAPIClient->
+ accountAuthTokenAttach(Utils::appStringToCoreString(token))
+ ->then([this](FlexiAPIClient::Response response){
+ qWarning() << "Attached";
+ emit qRCodeAttached();
+ })
+ ->error([this](FlexiAPIClient::Response response){
+ emit qRCodeNotAttached("Cannot attach"+ (response.body.empty() ? "" : " : " +Utils::coreStringToAppString(response.body)), response.code);
+ });
+}
// -----------------------------------------------------------------------------
@@ -431,6 +513,21 @@ void AssistantModel::setConfigFilename (const QString &configFilename) {
emit configFilenameChanged(configFilename);
}
+bool AssistantModel::getIsReadingQRCode() const{
+ return mIsReadingQRCode;
+}
+
+void AssistantModel::setIsReadingQRCode(bool isReading){
+ if( mIsReadingQRCode != isReading){
+ if( CoreManager::getInstance()->getCore()->qrcodeVideoPreviewEnabled() != isReading){
+ CoreManager::getInstance()->getCore()->enableQrcodeVideoPreview(isReading);
+ //CoreManager::getInstance()->getCore()->enableVideoPreview(isReading);
+ }
+ mIsReadingQRCode = isReading;
+ emit isReadingQRCodeChanged();
+ }
+}
+
// -----------------------------------------------------------------------------
QString AssistantModel::mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const {
diff --git a/linphone-app/src/components/assistant/AssistantModel.hpp b/linphone-app/src/components/assistant/AssistantModel.hpp
index dddfc05f1..a124f963e 100644
--- a/linphone-app/src/components/assistant/AssistantModel.hpp
+++ b/linphone-app/src/components/assistant/AssistantModel.hpp
@@ -27,78 +27,111 @@
// =============================================================================
class AssistantModel : public QObject {
- class Handlers;
-
- Q_OBJECT;
-
- Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged);
- Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged);
- Q_PROPERTY(QString countryCode READ getCountryCode WRITE setCountryCode NOTIFY countryCodeChanged);
- Q_PROPERTY(QString phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged);
- Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged);
- Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged);
- Q_PROPERTY(QString activationCode READ getActivationCode WRITE setActivationCode NOTIFY activationCodeChanged);
- Q_PROPERTY(QString configFilename READ getConfigFilename WRITE setConfigFilename NOTIFY configFilenameChanged);
-
+ class Handlers;
+
+ Q_OBJECT;
+
+ Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged);
+ Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged);
+ Q_PROPERTY(QString countryCode READ getCountryCode WRITE setCountryCode NOTIFY countryCodeChanged);
+ Q_PROPERTY(QString phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged);
+ Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged);
+ Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged);
+ Q_PROPERTY(QString activationCode READ getActivationCode WRITE setActivationCode NOTIFY activationCodeChanged);
+ Q_PROPERTY(QString configFilename READ getConfigFilename WRITE setConfigFilename NOTIFY configFilenameChanged);
+ Q_PROPERTY(bool isReadingQRCode READ getIsReadingQRCode WRITE setIsReadingQRCode NOTIFY isReadingQRCodeChanged);
+
public:
- AssistantModel (QObject *parent = Q_NULLPTR);
-
- Q_INVOKABLE void activate ();
- Q_INVOKABLE void create ();
- Q_INVOKABLE void login ();
-
- Q_INVOKABLE void reset ();
-
- Q_INVOKABLE bool addOtherSipAccount (const QVariantMap &map);
-
+ AssistantModel (QObject *parent = Q_NULLPTR);
+ virtual ~AssistantModel();
+
+ Q_INVOKABLE void activate ();
+ Q_INVOKABLE void create ();
+ Q_INVOKABLE void login ();
+
+ Q_INVOKABLE void reset ();
+
+ Q_INVOKABLE bool addOtherSipAccount (const QVariantMap &map);
+
+ Q_INVOKABLE void createTestAccount();
+ Q_INVOKABLE void generateQRCode();
+ Q_INVOKABLE void requestQRCode();
+ Q_INVOKABLE void readQRCode();
+
+ Q_INVOKABLE void attachAccount(const QString& token);
+
+ void checkLinkingAccount();
+
+public slots:
+ void onQRCodeFound(const std::string & result);
+ void onApiReceived(QString apiKey);
+ void newQRCodeNotReceivedTest();
+
signals:
- void emailChanged (const QString &email, const QString &error);
- void passwordChanged (const QString &password, const QString &error);
- void countryCodeChanged (const QString &countryCode);
- void phoneNumberChanged (const QString &phoneNumber, const QString &error);
- void usernameChanged (const QString &username, const QString &error);
- void displayNameChanged (const QString &displayName, const QString &error);
- void activationCodeChanged (const QString &activationCode);
-
- void activateStatusChanged (const QString &error);
- void createStatusChanged (const QString &error);
- void loginStatusChanged (const QString &error);
- void recoverStatusChanged (const QString &error);
-
- void configFilenameChanged (const QString &configFilename);
-
+ void emailChanged (const QString &email, const QString &error);
+ void passwordChanged (const QString &password, const QString &error);
+ void countryCodeChanged (const QString &countryCode);
+ void phoneNumberChanged (const QString &phoneNumber, const QString &error);
+ void usernameChanged (const QString &username, const QString &error);
+ void displayNameChanged (const QString &displayName, const QString &error);
+ void activationCodeChanged (const QString &activationCode);
+
+ void activateStatusChanged (const QString &error);
+ void createStatusChanged (const QString &error);
+ void loginStatusChanged (const QString &error);
+ void recoverStatusChanged (const QString &error);
+
+ void configFilenameChanged (const QString &configFilename);
+
+ void newQRCodeReceived(QString code);// code for QRCode generation.
+ void newQRCodeNotReceived(QString message, int errorCode);// The QRCode couldn't be generated. Return HTTP error code.
+ void provisioningTokenReceived(QString token);// Provisioning token to use
+ void isReadingQRCodeChanged();
+ void qRCodeFound(QString token);
+
+ void qRCodeAttached();
+ void qRCodeNotAttached(QString message, int errorCode);
+ void apiReceived(QString apiKey);
+
+
+
private:
- QString getEmail () const;
- void setEmail (const QString &email);
-
- QString getPassword () const;
- void setPassword (const QString &password);
-
- QString getCountryCode () const;
- void setCountryCode (const QString &countryCode);
-
- QString getPhoneNumber () const;
- void setPhoneNumber (const QString &phoneNumber);
-
- QString getUsername () const;
- void setUsername (const QString &username);
-
- QString getDisplayName () const;
- void setDisplayName (const QString &displayName);
-
- QString getActivationCode () const;
- void setActivationCode (const QString &activationCode);
-
- QString getConfigFilename () const;
- void setConfigFilename (const QString &configFilename);
-
- QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const;
-
- QString mCountryCode;
- QString mConfigFilename;
-
- std::shared_ptr mAccountCreator;
- std::shared_ptr mHandlers;
+ QString getEmail () const;
+ void setEmail (const QString &email);
+
+ QString getPassword () const;
+ void setPassword (const QString &password);
+
+ QString getCountryCode () const;
+ void setCountryCode (const QString &countryCode);
+
+ QString getPhoneNumber () const;
+ void setPhoneNumber (const QString &phoneNumber);
+
+ QString getUsername () const;
+ void setUsername (const QString &username);
+
+ QString getDisplayName () const;
+ void setDisplayName (const QString &displayName);
+
+ QString getActivationCode () const;
+ void setActivationCode (const QString &activationCode);
+
+ QString getConfigFilename () const;
+ void setConfigFilename (const QString &configFilename);
+
+ bool getIsReadingQRCode() const;
+ void setIsReadingQRCode(bool isReading);
+
+ QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreator::UsernameStatus status) const;
+
+ QString mCountryCode;
+ QString mConfigFilename;
+ QString mToken;
+ bool mIsReadingQRCode;
+
+ std::shared_ptr mAccountCreator;
+ std::shared_ptr mHandlers;
};
#endif // ASSISTANT_MODEL_H_
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp
index 710f6afc3..f35fcc41f 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp
@@ -323,11 +323,11 @@ void ConferenceInfoModel::deleteConferenceInfo(){
//-------------------------------------------------------------------------------------------------
-void ConferenceInfoModel::onStateChanged(linphone::ConferenceSchedulerState state){
+void ConferenceInfoModel::onStateChanged(linphone::ConferenceScheduler::State state){
qDebug() << "ConferenceInfoModel::onStateChanged: " << (int) state;
- if( state == linphone::ConferenceSchedulerState::Ready)
+ if( state == linphone::ConferenceScheduler::State::Ready)
emit conferenceCreated();
- else if( state == linphone::ConferenceSchedulerState::Error)
+ else if( state == linphone::ConferenceScheduler::State::Error)
emit conferenceCreationFailed();
}
void ConferenceInfoModel::onInvitationsSent(const std::list> & failedInvitations) {
diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp
index 3e5adfaee..2d260983d 100644
--- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp
+++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp
@@ -95,7 +95,7 @@ public:
// SCHEDULER
- virtual void onStateChanged(linphone::ConferenceSchedulerState state);
+ virtual void onStateChanged(linphone::ConferenceScheduler::State state);
virtual void onInvitationsSent(const std::list> & failedInvitations);
diff --git a/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.cpp b/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.cpp
index 43c8b2f5d..62aa35479 100644
--- a/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.cpp
+++ b/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.cpp
@@ -54,10 +54,10 @@ std::shared_ptr ConferenceScheduler::getConferenc
return mConferenceScheduler;
}
-void ConferenceScheduler::onStateChanged(linphone::ConferenceSchedulerState state) {
+void ConferenceScheduler::onStateChanged(linphone::ConferenceScheduler::State state) {
qDebug() << "ConferenceScheduler::onStateChanged : " << (int)state;
emit stateChanged(state);
- if( state == linphone::ConferenceSchedulerState::Ready) {
+ if( state == linphone::ConferenceScheduler::State::Ready) {
emit CoreManager::getInstance()->getHandlers()->conferenceInfoReceived(mConferenceScheduler->getInfo());
if( (mSendInvite & 1) == 1){
std::shared_ptr params = CoreManager::getInstance()->getCore()->createDefaultChatRoomParams();
diff --git a/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.hpp b/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.hpp
index 52155ad75..31d8da934 100644
--- a/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.hpp
+++ b/linphone-app/src/components/conferenceScheduler/ConferenceScheduler.hpp
@@ -36,13 +36,13 @@ public:
virtual ~ConferenceScheduler ();
std::shared_ptr getConferenceScheduler();
- virtual void onStateChanged(linphone::ConferenceSchedulerState state);
+ virtual void onStateChanged(linphone::ConferenceScheduler::State state);
virtual void onInvitationsSent(const std::list> & failedInvitations);
int mSendInvite = 1;// TODO : Enum for app = 1, email=2. Both = 3
signals:
- void stateChanged(linphone::ConferenceSchedulerState state);
+ void stateChanged(linphone::ConferenceScheduler::State state);
void invitationsSent(const std::list> & failedInvitations);
private:
diff --git a/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.cpp b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.cpp
index a4058301d..8b8e4de27 100644
--- a/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.cpp
+++ b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.cpp
@@ -33,7 +33,7 @@ ConferenceSchedulerListener::~ConferenceSchedulerListener () {
}
-void ConferenceSchedulerListener::onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceSchedulerState state) {
+void ConferenceSchedulerListener::onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceScheduler::State state) {
qDebug() << "ConferenceSchedulerListener::onStateChanged" << (int) state;
emit stateChanged(state);
}
diff --git a/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.hpp b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.hpp
index 86e518458..f1ba89e8b 100644
--- a/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.hpp
+++ b/linphone-app/src/components/conferenceScheduler/ConferenceSchedulerListener.hpp
@@ -32,11 +32,11 @@ public:
ConferenceSchedulerListener();
virtual ~ConferenceSchedulerListener();
- virtual void onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceSchedulerState state) override;
+ virtual void onStateChanged(const std::shared_ptr & conferenceScheduler, linphone::ConferenceScheduler::State state) override;
virtual void onInvitationsSent(const std::shared_ptr & conferenceScheduler, const std::list> & failedInvitations) override;
signals:
- void stateChanged(linphone::ConferenceSchedulerState state);
+ void stateChanged(linphone::ConferenceScheduler::State state);
void invitationsSent(const std::list> & failedInvitations);
};
diff --git a/linphone-app/src/components/core/CoreHandlers.cpp b/linphone-app/src/components/core/CoreHandlers.cpp
index 0600a10b7..135942be7 100644
--- a/linphone-app/src/components/core/CoreHandlers.cpp
+++ b/linphone-app/src/components/core/CoreHandlers.cpp
@@ -283,6 +283,10 @@ void CoreHandlers::onNotifyPresenceReceived (
emit presenceStatusReceived(linphoneFriend);
}
+void CoreHandlers::onQrcodeFound(const std::shared_ptr & core, const std::string & result){
+ emit foundQRCode(result);
+}
+
void CoreHandlers::onTransferStateChanged (
const shared_ptr &,
const shared_ptr &call,
diff --git a/linphone-app/src/components/core/CoreHandlers.hpp b/linphone-app/src/components/core/CoreHandlers.hpp
index 593d8e381..92717d58a 100644
--- a/linphone-app/src/components/core/CoreHandlers.hpp
+++ b/linphone-app/src/components/core/CoreHandlers.hpp
@@ -59,6 +59,7 @@ signals:
void ecCalibrationResult(linphone::EcCalibratorStatus status, int delayMs);
void setLastRemoteProvisioningState(const linphone::ConfiguringState &state);
void conferenceInfoReceived(const std::shared_ptr & conferenceInfo);
+ void foundQRCode(const std::string & result);
private:
// ---------------------------------------------------------------------------
@@ -166,6 +167,8 @@ private:
const std::shared_ptr &linphoneFriend
) override;
+ void onQrcodeFound(const std::shared_ptr & core, const std::string & result) override;
+
void onTransferStateChanged (
const std::shared_ptr &core,
const std::shared_ptr &call,
diff --git a/linphone-app/src/components/core/CoreManager.cpp b/linphone-app/src/components/core/CoreManager.cpp
index f974f0e4e..f2d675f5d 100644
--- a/linphone-app/src/components/core/CoreManager.cpp
+++ b/linphone-app/src/components/core/CoreManager.cpp
@@ -283,6 +283,8 @@ void CoreManager::createLinphoneCore (const QString &configPath) {
setOtherPaths();
mCore->enableFriendListSubscription(true);
mCore->enableRecordAware(true);
+ if(mCore->getAccountCreatorUrl() == "")
+ mCore->setAccountCreatorUrl(Constants::DefaultFlexiAPIURL);
}
void CoreManager::updateUserAgent(){
diff --git a/linphone-app/src/components/participant/ParticipantDeviceListener.cpp b/linphone-app/src/components/participant/ParticipantDeviceListener.cpp
index 64f99520c..bd595368e 100644
--- a/linphone-app/src/components/participant/ParticipantDeviceListener.cpp
+++ b/linphone-app/src/components/participant/ParticipantDeviceListener.cpp
@@ -34,7 +34,7 @@ void ParticipantDeviceListener::onIsSpeakingChanged(const std::shared_ptr & participantDevice, bool isMutedVar) {
- qInfo() << "onIsMuted " << isMutedVar << " vs " << participantDevice->getIsMuted();
+ qInfo() << "onIsMuted " << isMutedVar << " vs " << participantDevice->getIsMuted() << " for " << participantDevice->getAddress()->asString().c_str();
emit isMuted(participantDevice, isMutedVar);
}
diff --git a/linphone-app/src/components/settings/SettingsModel.cpp b/linphone-app/src/components/settings/SettingsModel.cpp
index 041b30671..d069dfac7 100644
--- a/linphone-app/src/components/settings/SettingsModel.cpp
+++ b/linphone-app/src/components/settings/SettingsModel.cpp
@@ -1481,6 +1481,10 @@ void SettingsModel::setDownloadFolder (const QString &folder) {
// -----------------------------------------------------------------------------
+QString SettingsModel::getRemoteProvisioningRootUrl() const{
+ return Utils::coreStringToAppString(mConfig->getString(UiSection, "remote_provisioning_root", Constants::RemoteProvisioningURL));
+}
+
QString SettingsModel::getRemoteProvisioning () const {
return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getProvisioningUri());
}
@@ -1488,7 +1492,7 @@ QString SettingsModel::getRemoteProvisioning () const {
void SettingsModel::setRemoteProvisioning (const QString &remoteProvisioning) {
QString urlRemoteProvisioning = remoteProvisioning;
if( QUrl(urlRemoteProvisioning).isRelative()) {
- urlRemoteProvisioning = QString(Constants::RemoteProvisioningURL) +"/"+ remoteProvisioning;
+ urlRemoteProvisioning = getRemoteProvisioningRootUrl() +"/"+ remoteProvisioning;
}
if (!CoreManager::getInstance()->getCore()->setProvisioningUri(Utils::appStringToCoreString(urlRemoteProvisioning)))
emit remoteProvisioningChanged(urlRemoteProvisioning);
@@ -1496,6 +1500,18 @@ void SettingsModel::setRemoteProvisioning (const QString &remoteProvisioning) {
emit remoteProvisioningNotChanged(urlRemoteProvisioning);
}
+bool SettingsModel::isQRCodeAvailable() const{
+ return linphone::Factory::get()->isQrcodeAvailable() && !!mConfig->getInt(UiSection, "use_qrcode", 1);
+}
+
+QString SettingsModel::getFlexiAPIUrl() const{
+ return Utils::coreStringToAppString(CoreManager::getInstance()->getCore()->getAccountCreatorUrl());
+}
+void SettingsModel::setFlexiAPIUrl (const QString &url){
+ CoreManager::getInstance()->getCore()->setAccountCreatorUrl(Utils::appStringToCoreString(url));
+ emit flexiAPIUrlChanged(url);
+}
+
// -----------------------------------------------------------------------------
bool SettingsModel::getExitOnClose () const {
diff --git a/linphone-app/src/components/settings/SettingsModel.hpp b/linphone-app/src/components/settings/SettingsModel.hpp
index 57b8d3c7d..728cbe227 100644
--- a/linphone-app/src/components/settings/SettingsModel.hpp
+++ b/linphone-app/src/components/settings/SettingsModel.hpp
@@ -194,6 +194,7 @@ class SettingsModel : public QObject {
Q_PROPERTY(int textMessageFontSize READ getTextMessageFontSize WRITE setTextMessageFontSize NOTIFY textMessageFontSizeChanged)
Q_PROPERTY(QString remoteProvisioning READ getRemoteProvisioning WRITE setRemoteProvisioning NOTIFY remoteProvisioningChanged)
+ Q_PROPERTY(QString flexiAPIUrl READ getFlexiAPIUrl WRITE setFlexiAPIUrl NOTIFY flexiAPIUrlChanged)
Q_PROPERTY(QString savedScreenshotsFolder READ getSavedScreenshotsFolder WRITE setSavedScreenshotsFolder NOTIFY savedScreenshotsFolderChanged)
Q_PROPERTY(QString savedCallsFolder READ getSavedCallsFolder WRITE setSavedCallsFolder NOTIFY savedCallsFolderChanged)
@@ -553,9 +554,14 @@ public:
QString getDownloadFolder () const;
void setDownloadFolder (const QString &folder);
+ QString getRemoteProvisioningRootUrl() const;
QString getRemoteProvisioning () const;
void setRemoteProvisioning (const QString &remoteProvisioning);
+ Q_INVOKABLE bool isQRCodeAvailable() const;
+ QString getFlexiAPIUrl() const;
+ void setFlexiAPIUrl (const QString &url);
+
bool getExitOnClose () const;
void setExitOnClose (bool value);
@@ -769,6 +775,7 @@ signals:
void remoteProvisioningChanged (const QString &remoteProvisioning);
void remoteProvisioningNotChanged (const QString &remoteProvisioning);
+ void flexiAPIUrlChanged (const QString &url);
void exitOnCloseChanged (bool value);
void mipmapEnabledChanged();
diff --git a/linphone-app/src/utils/Constants.cpp b/linphone-app/src/utils/Constants.cpp
index 7f75b6b7b..965f6afc4 100644
--- a/linphone-app/src/utils/Constants.cpp
+++ b/linphone-app/src/utils/Constants.cpp
@@ -67,6 +67,7 @@ constexpr char Constants::DefaultXmlrpcUri[];
constexpr char Constants::DefaultConferenceURI[];
constexpr char Constants::DefaultVideoConferenceURI[];
constexpr char Constants::DefaultLimeServerURL[];
+constexpr char Constants::DefaultFlexiAPIURL[];
constexpr char Constants::RemoteProvisioningURL[];
constexpr char Constants::DefaultAssistantRegistrationUrl[];
constexpr char Constants::DefaultAssistantLoginUrl[];
diff --git a/linphone-app/src/utils/Constants.hpp b/linphone-app/src/utils/Constants.hpp
index fb63b0cec..3daaa6b9e 100644
--- a/linphone-app/src/utils/Constants.hpp
+++ b/linphone-app/src/utils/Constants.hpp
@@ -72,8 +72,10 @@ public:
static constexpr char DefaultConferenceURI[] = "sip:conference-factory@sip.linphone.org";
static constexpr char DefaultVideoConferenceURI[] = "sip:videoconference-factory@sip.linphone.org";
static constexpr char DefaultLimeServerURL[] = "https://lime.linphone.org/lime-server/lime-server.php";
- static constexpr char RemoteProvisioningURL[] = "https://subscribe.linphone.org/flexiapi/provisioning";
-
+
+ static constexpr char DefaultFlexiAPIURL[] = "http://fs-test-sandbox.linphone.org/flexiapi/api/";// Need "/" at the end
+ static constexpr char RemoteProvisioningURL[] = "http://fs-test-sandbox.linphone.org/flexiapi/provisioning";
+
Q_PROPERTY(QString PasswordRecoveryUrl MEMBER PasswordRecoveryUrl CONSTANT)
Q_PROPERTY(QString CguUrl MEMBER CguUrl CONSTANT)
Q_PROPERTY(QString PrivatePolicyUrl MEMBER PrivatePolicyUrl CONSTANT)
diff --git a/linphone-app/src/utils/LinphoneEnums.cpp b/linphone-app/src/utils/LinphoneEnums.cpp
index 98731de8a..e2d547628 100644
--- a/linphone-app/src/utils/LinphoneEnums.cpp
+++ b/linphone-app/src/utils/LinphoneEnums.cpp
@@ -78,11 +78,11 @@ LinphoneEnums::ConferenceLayout LinphoneEnums::fromLinphone(const linphone::Conf
return static_cast(layout);
}
-linphone::ConferenceInfoState LinphoneEnums::toLinphone(const LinphoneEnums::ConferenceInfoState& state){
- return static_cast(state);
+linphone::ConferenceInfo::State LinphoneEnums::toLinphone(const LinphoneEnums::ConferenceInfoState& state){
+ return static_cast(state);
}
-LinphoneEnums::ConferenceInfoState LinphoneEnums::fromLinphone(const linphone::ConferenceInfoState& state){
+LinphoneEnums::ConferenceInfoState LinphoneEnums::fromLinphone(const linphone::ConferenceInfo::State& state){
return static_cast(state);
}
diff --git a/linphone-app/src/utils/LinphoneEnums.hpp b/linphone-app/src/utils/LinphoneEnums.hpp
index 97de1d92c..da2eb568f 100644
--- a/linphone-app/src/utils/LinphoneEnums.hpp
+++ b/linphone-app/src/utils/LinphoneEnums.hpp
@@ -123,14 +123,14 @@ LinphoneEnums::ConferenceLayout fromLinphone(const linphone::ConferenceLayout& l
enum ConferenceInfoState {
- ConferenceInfoStateNew = int(linphone::ConferenceInfoState::New),
- ConferenceInfoStateUpdated = int(linphone::ConferenceInfoState::Updated),
- ConferenceInfoStateCancelled = int(linphone::ConferenceInfoState::Cancelled)
+ ConferenceInfoStateNew = int(linphone::ConferenceInfo::State::New),
+ ConferenceInfoStateUpdated = int(linphone::ConferenceInfo::State::Updated),
+ ConferenceInfoStateCancelled = int(linphone::ConferenceInfo::State::Cancelled)
};
Q_ENUM_NS(ConferenceInfoState)
-linphone::ConferenceInfoState toLinphone(const LinphoneEnums::ConferenceInfoState& state);
-LinphoneEnums::ConferenceInfoState fromLinphone(const linphone::ConferenceInfoState& state);
+linphone::ConferenceInfo::State toLinphone(const LinphoneEnums::ConferenceInfoState& state);
+LinphoneEnums::ConferenceInfoState fromLinphone(const linphone::ConferenceInfo::State& state);
enum ParticipantDeviceState {
diff --git a/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml b/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml
index 707364276..4265de04f 100644
--- a/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml
+++ b/linphone-app/ui/modules/Common/Form/Buttons/AbstractTextButton.qml
@@ -28,6 +28,7 @@ Item {
property alias text: button.text
property bool enabled: true
property bool showBorder : false
+ property alias toggled : button.checked
property alias capitalization : button.capitalization
@@ -44,7 +45,7 @@ Item {
return colorDisabled
}
- return button.down
+ return button.down || button.checked
? colorPressed
: (button.hovered ? colorHovered : colorNormal)
}
@@ -54,7 +55,7 @@ Item {
return borderColorDisabled
}
- return button.down
+ return button.down || button.checked
? borderColorPressed
: (button.hovered ? borderColorHovered : borderColorNormal)
}
@@ -64,15 +65,16 @@ Item {
return textColorDisabled
}
- return button.down
+ return button.down || button.checked
? textColorPressed
: (button.hovered ? textColorHovered : textColorNormal)
}
// ---------------------------------------------------------------------------
-
- height: button.contentItem.implicitHeight + addHeight
- width: button.contentItem.implicitWidth + addWidth
+ property int fitHeight: button.contentItem.implicitHeight + addHeight
+ property int fitWidth: button.contentItem.implicitWidth + addWidth
+ height: fitHeight
+ width: fitWidth
// ---------------------------------------------------------------------------
diff --git a/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml b/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml
index 1c9922a64..c16ebf18d 100644
--- a/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml
+++ b/linphone-app/ui/modules/Linphone/Timeline/TimelineItem.qml
@@ -67,7 +67,7 @@ Item {
titleColor: isSelected
? TimelineStyle.contact.title.color.selected
: TimelineStyle.contact.title.color.normal
- showSubtitle: mainItem.timelineModel.chatRoomModel.isOneToOne || !mainItem.timelineModel.chatRoomModel.isConference
+ showSubtitle: mainItem.timelineModel.chatRoomModel && (mainItem.timelineModel.chatRoomModel.isOneToOne || !mainItem.timelineModel.chatRoomModel.isConference)
TooltipArea {
id: contactTooltip
text: mainItem.timelineModel && UtilsCpp.toDateTimeString(mainItem.timelineModel.chatRoomModel.lastUpdateTime)
diff --git a/linphone-app/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml b/linphone-app/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml
index da3e97aab..319e19139 100644
--- a/linphone-app/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml
+++ b/linphone-app/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml
@@ -1,4 +1,5 @@
import QtQuick 2.7
+import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
@@ -7,18 +8,19 @@ import Utils 1.0
import App.Styles 1.0
// =============================================================================
Item{
+
AssistantAbstractView {
- mainAction: requestBlock.execute
- mainActionEnabled: url.text.length > 0
- mainActionLabel: qsTr('confirmAction')
-
+ id: mainItem
title: qsTr('fetchRemoteConfigurationTitle')
- width: AssistantAbstractViewStyle.content.width
- height: AssistantAbstractViewStyle.content.height
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
- // ---------------------------------------------------------------------------
+ maximized: true
+ //: 'generate' : title button to generate a code.
+ property string generateButtonText: qsTr('generateLabel')
+ // ---------------------------------------------------------------------------
+ AssistantModel {
+ id: assistantModel
+ property string qrcode
+ }
Connections {
target: SettingsModel
@@ -38,41 +40,233 @@ Item{
onRemoteProvisioningNotChanged: requestBlock.stop(qsTr('remoteProvisioningError'))
}
+ Connections{
+ target: assistantModel
+ onNewQRCodeReceived: {assistantModel.qrcode = 'image://qrcode/'+code; requestBlock.stop('')}
+ onNewQRCodeNotReceived: requestBlock.stop(message)
+ onProvisioningTokenReceived: {url.text = token
+ SettingsModel.remoteProvisioning = url.text
+ assistantModel.qrcode = ''
+ requestBlock.stop('')}
+
+ onQRCodeAttached: requestBlock.stop('Attached')
+ onQRCodeNotAttached: requestBlock.stop(message)
+
+ onQRCodeFound: {
+ if(qRCodeRead.currentIndex == 0)
+ url.text = token;
+ else
+ assistantModel.attachAccount(token)
+ }
+ }
// ---------------------------------------------------------------------------
- Column {
- anchors.fill: parent.contentItem
- anchors.topMargin: AssistantAbstractViewStyle.info.spacing
- width: AssistantAbstractViewStyle.content.width
- height: AssistantAbstractViewStyle.content.height
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: 0
+ spacing: 0
- Form {
- orientation: Qt.Vertical
- width: parent.width
+ Text{
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: urlLayout.width
- FormLine {
- FormGroup {
- label: qsTr('urlLabel')
-
- TextField {
- id: url
- }
- }
+ font.pointSize: FetchRemoteConfigurationStyle.fieldTitles.pointSize
+ font.weight: Font.Bold
+ color: FetchRemoteConfigurationStyle.fieldTitles.color
+
+
+ text: qsTr('urlLabel')
+ }
+ RowLayout{
+ id: urlLayout
+ Layout.preferredHeight: fetchButton.fitHeight
+ Layout.alignment: Qt.AlignCenter
+
+ spacing: 10
+
+ TextField {
+ Layout.preferredWidth: mainItem.width/2
+ id: url
}
+ TextButtonB {
+ id: fetchButton
+ Layout.preferredWidth: fitWidth
+ Layout.preferredHeight: fitHeight
+ addHeight: 15
+
+ onClicked: SettingsModel.remoteProvisioning = url.text
+
+ text: qsTr('confirmAction')
+ enabled: url.text.length > 0
+ }
+ /*Dev Tool
+ TextButtonB {
+ id: testButton
+ Layout.preferredWidth: fitWidth
+ Layout.preferredHeight: fitHeight
+
+ onClicked: assistantModel.createTestAccount()
+
+ text: 'Create Test'
+ }*/
}
RequestBlock {
id: requestBlock
-
action: (function () {
- SettingsModel.remoteProvisioning = url.text
})
+ Layout.preferredWidth: parent.width
- width: parent.width
+ }
+ Text{
+ Layout.topMargin: 15
+ Layout.alignment: Qt.AlignCenter
+ visible: SettingsModel.isQRCodeAvailable()
+
+ font.pointSize: FetchRemoteConfigurationStyle.fieldTitles.pointSize
+ font.weight: Font.Bold
+ font.capitalization: Font.Capitalize
+ color: FetchRemoteConfigurationStyle.fieldTitles.color
+ //: 'or' : conjunction to choose between options.
+ text: qsTr('or')
+ }
+ ColumnLayout{
+ id: simpleQRCodeOptionsView
+ Layout.fillWidth: true
+ Layout.margins: 15
+ visible: SettingsModel.isQRCodeAvailable() && !SettingsModel.developerSettingsEnabled
+ Layout.alignment: Qt.AlignCenter
+ spacing: 15
+ Rectangle{
+ Layout.fillHeight: true
+ Layout.preferredWidth: height
+ Layout.alignment: Qt.AlignCenter
+ border.color: FetchRemoteConfigurationStyle.qRCode.borderColor
+ radius: 20
+ border.width: 1
+ Text{
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.margins: 10
+ anchors.verticalCenter: parent.verticalCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ visible: assistantModel.qrcode == ''
+ wrapMode: Text.WordWrap
+ font.pointSize: FetchRemoteConfigurationStyle.explanationQRCode.pointSize
+ color: FetchRemoteConfigurationStyle.explanationQRCode.color
+ //: 'Click on %1 to obtain your remote provisioning QR code' : Describe how to get a remote provisioning QR code by clicking on %1 button (1% is the text in button)
+ text : qsTr('remoteProvisioningHow').arg(mainItem.generateButtonText)
+ }
+ Image{
+ anchors.fill: parent
+ anchors.margins: 20
+ sourceSize.width: width
+ sourceSize.height: height
+ source: assistantModel.qrcode
+ visible: source != ''
+ }
+ }
+ Text{
+ Layout.fillWidth: true
+ Layout.preferredHeight: contentHeight
+ Layout.alignment: Qt.AlignCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ visible: assistantModel.qrcode != ''
+ wrapMode: Text.WordWrap
+ font.pointSize: FetchRemoteConfigurationStyle.explanationQRCode.pointSize
+ color: FetchRemoteConfigurationStyle.explanationQRCode.color
+ //: 'Scan the QR code with your phone' : Explain how to use the QRCode by flasing it.
+ text: qsTr('scanQRCode') + '\n'
+ //: 'In your app go in assistant - QR code provisioning' : Describe where to flash the QRCode in the mobile application.
+ +qsTr('scanQRCodeWhere')
+ }
+ TextButtonB {
+ Layout.alignment: Qt.AlignCenter
+ text: mainItem.generateButtonText
+ onClicked: assistantModel.requestQRCode()
+ capitalization: Font.AllUppercase
+ }
+ }
+//------------------------------------------------------------------
+// Developer Section
+//------------------------------------------------------------------
+ GridLayout{
+ id: allQRCodeOptionsView
+ Layout.fillWidth: true
+ Layout.margins: 15
+ visible: SettingsModel.isQRCodeAvailable() && SettingsModel.developerSettingsEnabled
+ columns: 2
+ RowLayout{
+ Layout.fillWidth: true
+ ComboBox {
+ id: qRCodeGeneration
+
+ model: ['URL', 'Attach token']
+ currentIndex:0
+ Component.onCompleted: {}
+ }
+ TextButtonB {
+ text: mainItem.generateButtonText
+ capitalization: Font.AllUppercase
+ onClicked: if(qRCodeGeneration.currentIndex == 0 )
+ assistantModel.generateQRCode()
+ else
+ assistantModel.requestQRCode()
+ }
+ Item{
+ Layout.fillWidth: true
+ }
+ }
+ RowLayout{
+ Layout.fillWidth: true
+ Item{
+ Layout.fillWidth: true
+ }
+ ComboBox {
+ id: qRCodeRead
+
+ model: ['URL', 'Attach token']
+ currentIndex:0
+ Component.onCompleted: {}
+ }
+ TextButtonB {
+ id: qQRCodeReadButton
+ text: 'Read'
+ onClicked:assistantModel.readQRCode()
+
+ toggled: assistantModel.isReadingQRCode
+ }
+ }
+ Image{
+ Layout.fillHeight: true
+ Layout.preferredWidth: height
+ Layout.alignment: Qt.AlignCenter
+ sourceSize.width: width
+ sourceSize.height: height
+ source: assistantModel.qrcode
+ visible: source != ''
+ }
+ CameraSticker{
+ Layout.fillHeight: true
+ Layout.preferredWidth: height
+ Layout.alignment: Qt.AlignCenter
+ showUsername: false
+ showCustomButton: false
+ visible: allQRCodeOptionsView.visible && assistantModel.isReadingQRCode
+ deactivateCamera: !visible
+ isPreview: true
+ }
+ }
+ Item{
+ Layout.fillWidth: true
+ Layout.fillHeight: true
}
}
-
}
Component.onCompleted: {
if( !CoreManager.isLastRemoteProvisioningGood() )
diff --git a/linphone-app/ui/views/App/Styles/Main/Assistant/FetchRemoteConfigurationStyle.qml b/linphone-app/ui/views/App/Styles/Main/Assistant/FetchRemoteConfigurationStyle.qml
new file mode 100644
index 000000000..c900030ea
--- /dev/null
+++ b/linphone-app/ui/views/App/Styles/Main/Assistant/FetchRemoteConfigurationStyle.qml
@@ -0,0 +1,36 @@
+pragma Singleton
+import QtQml 2.2
+
+import ColorsList 1.0
+import Units 1.0
+// =============================================================================
+
+QtObject {
+ property string sectionName: 'FetchRemoteConfiguration'
+
+ property QtObject fieldTitles: QtObject{
+ property int pointSize: Units.dp * 10
+ property color color: ColorsList.add(sectionName+'_url_title', 'j').color
+ }
+ property QtObject qRCode : QtObject{
+ property color borderColor: ColorsList.add(sectionName+'_qrcode_border', 'border_light').color
+ }
+ property QtObject explanationQRCode : QtObject{
+ property int pointSize: Units.dp * 9
+ property color color: ColorsList.add(sectionName+'_qrcode_text', 'j').color
+ }
+
+ property QtObject checkBox: QtObject {
+ property int width: 300
+ }
+ property QtObject warningBlock: QtObject {
+ property int spacing: 10
+ property int pointSize: Units.dp * 10
+ property color color: ColorsList.add(sectionName+'_description', 'g').color
+
+ property QtObject contactUrl: QtObject {
+ property color color: ColorsList.add(sectionName+'_url', 'i').color
+ property int pointSize: Units.dp * 9
+ }
+ }
+}
diff --git a/linphone-app/ui/views/App/Styles/qmldir b/linphone-app/ui/views/App/Styles/qmldir
index 1eb1765b1..add72cbbe 100644
--- a/linphone-app/ui/views/App/Styles/qmldir
+++ b/linphone-app/ui/views/App/Styles/qmldir
@@ -28,6 +28,7 @@ singleton ActivateAppSipAccountWithPhoneNumberStyle 1.0 Main/Assistant/Acti
singleton AssistantAbstractViewStyle 1.0 Main/Assistant/AssistantAbstractViewStyle.qml
singleton AssistantHomeStyle 1.0 Main/Assistant/AssistantHomeStyle.qml
singleton CreateAppSipAccountStyle 1.0 Main/Assistant/CreateAppSipAccountStyle.qml
+singleton FetchRemoteConfigurationStyle 1.0 Main/Assistant/FetchRemoteConfigurationStyle.qml
singleton UseAppSipAccountStyle 1.0 Main/Assistant/UseAppSipAccountStyle.qml
singleton AssistantStyle 1.0 Main/AssistantStyle.qml
diff --git a/linphone-sdk b/linphone-sdk
index 51e5432a9..8287aa205 160000
--- a/linphone-sdk
+++ b/linphone-sdk
@@ -1 +1 @@
-Subproject commit 51e5432a98a42a889e7cbb4dba52c5be3b433d69
+Subproject commit 8287aa2050536c6810ebc07cf13db579f091e1b5