Skip to content
Snippets Groups Projects
Commit 29849316 authored by Kateryna Kostiuk's avatar Kateryna Kostiuk Committed by Andreas Traczyk
Browse files

updater: add sparkle

- add sparkle submodule
- add an option to enable sparkle
- modify entitlements
- cleanup Info.plist

Gitlab: #578
Change-Id: I7f562112a72a33e008ab316479fbaa68dc0e07f1
parent 6b7c2505
No related branches found
No related tags found
No related merge requests found
Showing with 502 additions and 190 deletions
...@@ -2,3 +2,7 @@ ...@@ -2,3 +2,7 @@
path = 3rdparty/qrencode-win32 path = 3rdparty/qrencode-win32
url = https://github.com/BlueDragon747/qrencode-win32.git url = https://github.com/BlueDragon747/qrencode-win32.git
ignore = dirty ignore = dirty
[submodule "sparkle/Sparkle"]
path = sparkle/Sparkle
url = https://github.com/sparkle-project/Sparkle.git
ignore = dirty
...@@ -98,7 +98,6 @@ set(COMMON_SOURCES ...@@ -98,7 +98,6 @@ set(COMMON_SOURCES
${SRC_DIR}/accountlistmodel.cpp ${SRC_DIR}/accountlistmodel.cpp
${SRC_DIR}/networkmanager.cpp ${SRC_DIR}/networkmanager.cpp
${SRC_DIR}/instancemanager.cpp ${SRC_DIR}/instancemanager.cpp
${SRC_DIR}/updatemanager.cpp
${SRC_DIR}/main.cpp ${SRC_DIR}/main.cpp
${SRC_DIR}/smartlistmodel.cpp ${SRC_DIR}/smartlistmodel.cpp
${SRC_DIR}/utils.cpp ${SRC_DIR}/utils.cpp
...@@ -214,7 +213,9 @@ if(MSVC) ...@@ -214,7 +213,9 @@ if(MSVC)
) )
list(APPEND COMMON_SOURCES list(APPEND COMMON_SOURCES
${SRC_DIR}/connectivitymonitor.cpp) ${SRC_DIR}/connectivitymonitor.cpp
${SRC_DIR}/updatemanager.cpp
)
# preprocessor defines # preprocessor defines
add_definitions(-DUNICODE -DQT_NO_DEBUG -DNDEBUG) add_definitions(-DUNICODE -DQT_NO_DEBUG -DNDEBUG)
...@@ -269,7 +270,8 @@ elseif (NOT APPLE) ...@@ -269,7 +270,8 @@ elseif (NOT APPLE)
list(APPEND COMMON_SOURCES list(APPEND COMMON_SOURCES
${SRC_DIR}/xrectsel.c ${SRC_DIR}/xrectsel.c
${SRC_DIR}/dbuserrorhandler.cpp ${SRC_DIR}/dbuserrorhandler.cpp
${SRC_DIR}/connectivitymonitor.cpp) ${SRC_DIR}/connectivitymonitor.cpp
${SRC_DIR}/updatemanager.cpp)
list(APPEND COMMON_HEADERS list(APPEND COMMON_HEADERS
${SRC_DIR}/dbuserrorhandler.h ${SRC_DIR}/dbuserrorhandler.h
${SRC_DIR}/xrectsel.h) ${SRC_DIR}/xrectsel.h)
...@@ -348,10 +350,10 @@ elseif (NOT APPLE) ...@@ -348,10 +350,10 @@ elseif (NOT APPLE)
find_library(ringclient ringclient ${LRCLIBDIR} NO_DEFAULT_PATH) find_library(ringclient ringclient ${LRCLIBDIR} NO_DEFAULT_PATH)
find_library(qrencode qrencode) find_library(qrencode qrencode)
find_library(X11 X11) find_library(X11 X11)
else() else() # APPLE
list(APPEND COMMON_SOURCES list(APPEND COMMON_SOURCES
${SRC_DIR}/connectivitymonitor.mm) ${SRC_DIR}/os/macos/updatemanager.mm
find_package(PkgConfig REQUIRED) ${SRC_DIR}/os/macos/connectivitymonitor.mm)
if(NOT DEFINED LRC) if(NOT DEFINED LRC)
if(EXISTS ${PROJECT_SOURCE_DIR}/../install/lrc) if(EXISTS ${PROJECT_SOURCE_DIR}/../install/lrc)
set(LRC ${PROJECT_SOURCE_DIR}/../install/lrc) set(LRC ${PROJECT_SOURCE_DIR}/../install/lrc)
...@@ -388,9 +390,24 @@ else() ...@@ -388,9 +390,24 @@ else()
find_library(ringclient ringclient ${LRCLIBDIR} NO_DEFAULT_PATH) find_library(ringclient ringclient ${LRCLIBDIR} NO_DEFAULT_PATH)
find_library(SYSTEM_CONFIGURATUION SystemConfiguration) find_library(SYSTEM_CONFIGURATUION SystemConfiguration)
SET(myApp_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/images/jami.icns) set(myApp_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/images/jami.icns)
SET_SOURCE_FILES_PROPERTIES(${myApp_ICON} PROPERTIES set_source_files_properties(${myApp_ICON} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources) MACOSX_PACKAGE_LOCATION Resources)
if(ENABLE_SPARKLE)
message("Sparkle auto-update enabled")
find_library(SPARKLE_FRAMEWORK
NAMES Sparkle
HINTS ${CMAKE_CURRENT_SOURCE_DIR}/sparkle)
add_definitions(-DENABLE_SPARKLE)
message("Sparkle is here:" ${SPARKLE_FRAMEWORK})
set(PUBLIC_KEY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sparkle/dsa_pub.pem")
set_source_files_properties(${PUBLIC_KEY_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
set(PUBLIC_KEY ${PUBLIC_KEY_PATH})
endif()
if(BETA)
message(STATUS "Beta config enabled")
add_definitions(-DBETA)
endif()
endif() endif()
# Qt find package # Qt find package
...@@ -607,12 +624,14 @@ elseif (NOT APPLE) ...@@ -607,12 +624,14 @@ elseif (NOT APPLE)
add_custom_target(uninstall add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
else() else()
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/resources/images/jami.icns) set(resources ${CMAKE_CURRENT_SOURCE_DIR}/resources/images/jami.icns)
target_link_libraries(${PROJECT_NAME} PRIVATE set(libs ${QT_LIBS} ${LRC_LIB_NAME} ${SYSTEM_CONFIGURATUION} qrencode)
${QT_LIBS} if(ENABLE_SPARKLE)
${LRC_LIB_NAME} set(resources ${resources} ${PUBLIC_KEY} ${SPARKLE_FRAMEWORK})
${SYSTEM_CONFIGURATUION} set(libs ${libs} ${SPARKLE_FRAMEWORK})
qrencode) endif(ENABLE_SPARKLE)
target_sources(${PROJECT_NAME} PRIVATE ${resources})
target_link_libraries(${PROJECT_NAME} PRIVATE ${libs})
# translations # translations
if(Qt${QT_VERSION_MAJOR}LinguistTools_FOUND) if(Qt${QT_VERSION_MAJOR}LinguistTools_FOUND)
...@@ -641,16 +660,18 @@ else() ...@@ -641,16 +660,18 @@ else()
MACOSX_BUNDLE_EXECUTABLE_NAME "${PROJ_NAME}" MACOSX_BUNDLE_EXECUTABLE_NAME "${PROJ_NAME}"
MACOSX_BUNDLE_ICON_FILE "jami.icns" MACOSX_BUNDLE_ICON_FILE "jami.icns"
MACOSX_BUNDLE_GUI_IDENTIFIER "${BUNDLE_ID}" MACOSX_BUNDLE_GUI_IDENTIFIER "${BUNDLE_ID}"
MACOSX_BUNDLE_BUNDLE_NAME "${PROJ_NAME}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${JAMI_VERSION}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${JAMI_VERSION}"
MACOSX_BUNDLE_BUNDLE_VERSION "${JAMI_BUILD}" MACOSX_BUNDLE_BUNDLE_VERSION "${JAMI_BUILD}"
MACOSX_BUNDLE_COPYRIGHT "${PROJ_COPYRIGHT}" MACOSX_BUNDLE_COPYRIGHT "${PROJ_COPYRIGHT}"
SPARKLE_URL "${SPARKLE_URL}"
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/Jami.entitlements" XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/Jami.entitlements"
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE) XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -DQML_SRC_DIR=${SRC_DIR} COMMAND ${CMAKE_COMMAND} -DQML_SRC_DIR=${SRC_DIR}
-DMAC_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin -DMAC_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin
-DEXE_NAME="${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app" -DEXE_NAME="${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app"
-DSPARKLE_PATH=${SPARKLE_FRAMEWORK}
-DENABLE_SPARKLE=${ENABLE_SPARKLE}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos_qt_deploy.cmake) -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos_qt_deploy.cmake)
endif() endif()
......
message("Qt deploying in dir " ${QML_SRC_DIR}) message("Qt deploying in dir " ${QML_SRC_DIR})
execute_process(COMMAND "${MAC_DEPLOY_QT_PATH}/macdeployqt" execute_process(COMMAND "${MAC_DEPLOY_QT_PATH}/macdeployqt"
${EXE_NAME} ${EXE_NAME}
-qmldir=${QML_SRC_DIR}) -qmldir=${QML_SRC_DIR})
if(${ENABLE_SPARKLE} MATCHES true)
file(COPY ${SPARKLE_PATH} DESTINATION ${EXE_NAME}/Contents/Frameworks/)
endif()
\ No newline at end of file
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> <string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
...@@ -20,16 +20,16 @@ ...@@ -20,16 +20,16 @@
<string>10.13</string> <string>10.13</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> <string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.social-networking</string> <string>public.app-category.social-networking</string>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string> <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key> <key>SUPublicDSAKeyFile</key>
<string>True</string> <string>dsa_pub.pem</string>
<key>SUFeedURL</key>
<string>${SPARKLE_URL}</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSCameraUsageDescription</key> <key>NSCameraUsageDescription</key>
<string>Jami requires to access your camera to make calls and record video</string> <string>Jami requires to access your camera to make calls and record video</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.device.camera</key> <key>com.apple.security.device.camera</key>
<true/> <true/>
<key>com.apple.security.device.microphone</key> <key>com.apple.security.device.audio-input</key>
<true/> <true/>
<key>com.apple.security.files.user-selected.read-write</key> <key>com.apple.security.files.user-selected.read-write</key>
<true/> <true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
</dict> </dict>
</plist> </plist>
Subproject commit 2195ee0883efc92828a0cf33b830f43f9bd7e01b
-----BEGIN PUBLIC KEY-----
MIIGRzCCBDoGByqGSM44BAEwggQtAoICAQCp4+JqCDyIMIMGtvpMvEPsQJ2SLJrt
y16KsLNmcUXLMMSmHdiC2EEZMhfp4OyuXwLGewA1NXBrBS6+6GidA0hh/IhclMUs
9kjzplVK4mOdKdSvFwuoJ9fdth+ySAXnhpcyLVFKQeoZ/jP20IhW9p+qZE4EMUlx
Pmls+MbNcZLu/HKiGI4XMN2K4yCxLSFjlpEPcT4yBYAZb+YRdY0v2HK3e9Jnja1b
Jfm23NaTRxkWzAu2Cm2S8G7JRo3Uuaw7RUmaAkmVWXFC0ZloGKBSeey6y1EuUtVy
dju3DRVI3RuvmB4yFJvdfgctTR2U6N26H733aOLFsvsSr6/hNp7q0ryDEfjqyW+R
SJwKZIRwl0WTsxwUzw+OejQH9CNcgkRaPgWBntnZ4OWSr2gFPkolt+VpLhSvKiSb
0ef3vZBuTp3KNCDGE20OVfQSeCstUyLZpLeG7tRyJEP/aCni9YTpIhZ5B9XNFe2J
jfzZE2VefKJWpxI1THfPgb0hto6zBuc8kpcKRPqwTRUHQuNwjAuAUKFV3GM9aoUC
KISWXPg2p1z8LgkuM8sgGEhn0BYEfpJFP3wc1OtIlv0t8Bqm1QR1y6hD/uxCYqq+
KR9/0eOsNH7dO/+7ydZjvVcBZ3TeGhvLQB/0Iic4Y895WMvN8bSB7NOZ8ODesO0J
zg2UkMdxdntiKQIhAKISld6gn3g1WSPXvWqT9mZzBly0hXr4DnGI1UtCeQm3AoIC
AQCMiu6knB8mbhcb7bOGhm3JEfi42+j3zavBYOga7LxP18Fobbf+5bHP3kMdNx8y
Paf0q0BkGtRC0WyH0ja05vR0bS9dSUT7qshQXm+/BsA/fnWPC54NcGSfRlj1UqHc
NN39r68EseO7w+w5x1gYFY7Jx/wJqR7gbYgS2GhgIrUo4+vBurl2bVtx6cAwsNXa
h0GUPAGQUu6qJaM5cpZL2Fkx+ac73q9i3WAlCECrkLpvOkLBSbYNvRR1rlhGawGr
Z96zEBEcW5FPJvPsjY2WaOvaRfGF9Y0MK8WXptdxY41jdts7n7kRKuwheUrm0bHm
aCRkGwhtc6hsMdrSzNFLDDScaSjYMx5erqnAKMyieyoiD8gyYN5mhZUokTBdpT1m
n7lrpQ0KfJtNKFtNUfNmU406vMEiTPKG4wxX/RxdzUqLSKNV1j0JHN6kx4Sq/vLN
EzO85ZaA79nBd2/8+ktWRiOuCiLu913Obgw3muNKYNVmH6iJibAYP+n7uUZHCzO4
MxccO5gy1umgTx/16Sya5ov+xt7CmS7kE4M4GzQ+AwXqzx3Mo8O72OWJP7RoRPxt
KTNiNZcjFrPkP4MkAogKNDt3McUXmKzfWEa+EvKHtXav7yiKoZ/kmQCawYQyvKFP
oBloHZ5N2iPnRGfABmFk/exF1Nb2dlhtD1hNYqtD3IWmVAOCAgUAAoICAFSPpbKF
wWcMAwTP7nEWZUr/8efPftwR2Q3F00dbh3ND+Yv7VRam6br+sPnrrPElWL+pPoFy
Vg7qJ6qmsOBgB+dDSiJ5w5L+aIj+vtmQHyCbbLTkCqzC5AO4pMaaXhg5hRQJw6JN
VkLByDsqHmjGG5ZLILzzKLi88X5Tz/Zz5FHWisnwRSGQaoZ5xJOCLfPLTOnASB/Q
uR5nBpYjImZslsPnDwTXVLqqOFo2TiQ3BXGV3BGpP83jaoDSVMjgc2NJNLw7X++b
mEFkALkG9uhhO57dTShwI+S3IzJfIBhSFW59bkY/N0f8peKAiUXmi3M/QWCvfh4k
+WRBaRiq+Ap+wV+IM+PH/INm0uEJ97mP5+7dPMZDNq1iPnJOKhqyXskq6i/Z9eg5
ZzgBw6Pxj6cNhZeg8OQuTfCGIV0m0FtfOZZVUs6l1JlMGb9bGbx2cDJBoI1DQxpG
X01TCtyNF4ShHbFmMG4JLuxBm99YuUJud2wPXToD9pxGWbh7naJwHzL7ywQQ/A0+
gSPE436MLSYPVeGr1RdIxFudZcoGZ2gG6V1aqZfNNlVO++UQ0wNTecFMPhdaC4O/
mnufQC8fSX9qBdnuWfkQQk8bE0kvqz4WSZ+B9Q7bEr7XeOcWibscCslIM2Rs68DK
ZnO5P9x/rPIJLCXY4xQYBryQCMu6JC5ibWzP
-----END PUBLIC KEY-----
#!/bin/bash
set -e
set -o pipefail
if [ "$#" -ne 2 ]; then
echo "Usage: $0 update_archive private_key"
exit 1
fi
openssl=/usr/bin/openssl
$openssl dgst -sha1 -binary < "$1" | $openssl dgst -dss1 -sign "$2" | base64 $BASE64_OPTS
#!/bin/bash
# Take the package to add as argument ./sparkle-xml-updater.sh jami.dmg
REPO_FOLDER=$1
SPARKLE_FILE=$2
REPO_URL=$3
PACKAGE=$4
DSA_KEY=$5
CHANNEL_NAME=$6
VERSION=$7
BUILD=$8
if [ ! -f ${PACKAGE} -o ! -f ${DSA_KEY} ]; then
echo "Can't find package or dsa key, aborting..."
exit 1
fi
if [ -f ${REPO_FOLDER}/${SPARKLE_FILE} ]; then
ITEMS=$(sed -n "/<item>/,/<\/item>/p" ${REPO_FOLDER}/${SPARKLE_FILE})
fi
PACKAGE_SIZE=`stat -f%z ${PACKAGE}`
DATE_RFC2822=`date "+%a, %d %b %Y %T %z"`
cat << EOFILE > ${REPO_FOLDER}/${SPARKLE_FILE}
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>${CHANNEL_NAME}</title>
<link>${REPO_URL}/${SPARKLE_FILE}</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>"${CHANNEL_NAME}-${BUILD}"</title>
<pubDate>$DATE_RFC2822</pubDate>
<sparkle:version>${BUILD}</sparkle:version>
<sparkle:shortVersionString>${VERSION}</sparkle:shortVersionString>
<sparkle:minimumSystemVersion>10.13</sparkle:minimumSystemVersion>
<enclosure url="${REPO_URL}/$(basename ${PACKAGE})" length="$PACKAGE_SIZE" type="application/octet-stream" sparkle:dsaSignature="$(./sign_update.sh ${PACKAGE} ${DSA_KEY})" />
</item>
$(echo -e "${ITEMS}")
</channel>
</rss>
EOFILE
...@@ -155,10 +155,12 @@ ApplicationWindow { ...@@ -155,10 +155,12 @@ ApplicationWindow {
windowSettingsLoaded = true windowSettingsLoaded = true
// Quiet check for updates on start if set to. // Quiet check for updates on start if set to.
if (Qt.platform.os.toString() !== "osx") {
if (UtilsAdapter.getAppValue(Settings.AutoUpdate)) { if (UtilsAdapter.getAppValue(Settings.AutoUpdate)) {
UpdateManager.checkForUpdates(true) UpdateManager.checkForUpdates(true)
UpdateManager.setAutoUpdateCheck(true) UpdateManager.setAutoUpdateCheck(true)
} }
}
// Handle a start URI if set as start option. // Handle a start URI if set as start option.
MainApplication.handleUriAction(); MainApplication.handleUriAction();
...@@ -190,7 +192,7 @@ ApplicationWindow { ...@@ -190,7 +192,7 @@ ApplicationWindow {
Connections { Connections {
target: { target: {
if (Qt.platform.os !== "windows" && Qt.platform.os !== "macos") if (Qt.platform.os.toString() !== "windows" && Qt.platform.os.toString() !== "osx")
return DBusErrorHandler return DBusErrorHandler
return null return null
} }
...@@ -220,7 +222,7 @@ ApplicationWindow { ...@@ -220,7 +222,7 @@ ApplicationWindow {
JamiQmlUtils.mainApplicationScreen = root.screen JamiQmlUtils.mainApplicationScreen = root.screen
if (Qt.platform.os !== "windows" && Qt.platform.os !== "macos") if (Qt.platform.os.toString() !== "windows" && Qt.platform.os.toString() !== "osx")
DBusErrorHandler.setActive(true) DBusErrorHandler.setActive(true)
} }
} }
File moved
/*
* Copyright (C) 2021-2022 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "updatemanager.h"
#ifdef ENABLE_SPARKLE
#include <Sparkle/Sparkle.h>
#endif
#ifdef BETA
static constexpr bool isBeta = true;
#else
static constexpr bool isBeta = false;
#endif
#ifdef ENABLE_SPARKLE
struct UpdateManager::Impl
{
Impl()
{
updaterController_ = [[SPUStandardUpdaterController alloc] initWithStartingUpdater: true
updaterDelegate: nil
userDriverDelegate: nil];
};
void checkForUpdates()
{
[updaterController_ checkForUpdates: nil];
};
void setAutoUpdateCheck(bool state)
{
updaterController_.updater.automaticallyChecksForUpdates = state;
};
bool isAutoUpdaterEnabled()
{
return updaterController_.updater.automaticallyChecksForUpdates;
};
bool isUpdaterEnabled() {
return true;
};
SPUStandardUpdaterController* updaterController_;
};
#else
struct UpdateManager::Impl
{
void checkForUpdates() {};
void setAutoUpdateCheck(bool state) {};
bool isAutoUpdaterEnabled()
{
return false;
};
bool isUpdaterEnabled()
{
return false;
};
};
#endif
UpdateManager::UpdateManager(const QString& url,
ConnectivityMonitor* cm,
LRCInstance* instance,
QObject* parent)
: NetWorkManager(cm, parent)
, pimpl_(std::make_unique<Impl>())
{}
UpdateManager::~UpdateManager()
{}
void
UpdateManager::checkForUpdates(bool quiet)
{
Q_UNUSED(quiet)
pimpl_->checkForUpdates();
}
void
UpdateManager::applyUpdates(bool beta)
{
Q_UNUSED(beta)
}
void
UpdateManager::cancelUpdate()
{}
void
UpdateManager::setAutoUpdateCheck(bool state)
{
pimpl_->setAutoUpdateCheck(state);
}
bool
UpdateManager::isCurrentVersionBeta()
{
return isBeta;
}
bool
UpdateManager::isUpdaterEnabled()
{
return pimpl_->isUpdaterEnabled();
}
bool
UpdateManager::isAutoUpdaterEnabled()
{
return pimpl_->isAutoUpdaterEnabled();
}
...@@ -23,6 +23,7 @@ import net.jami.Models 1.1 ...@@ -23,6 +23,7 @@ import net.jami.Models 1.1
import net.jami.Adapters 1.1 import net.jami.Adapters 1.1
import net.jami.Enums 1.1 import net.jami.Enums 1.1
import net.jami.Constants 1.1 import net.jami.Constants 1.1
import net.jami.Helpers 1.1
import "../../commoncomponents" import "../../commoncomponents"
...@@ -99,7 +100,7 @@ Rectangle { ...@@ -99,7 +100,7 @@ Rectangle {
Layout.leftMargin: JamiTheme.preferredMarginSize Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.bottomMargin: JamiTheme.preferredMarginSize Layout.bottomMargin: JamiTheme.preferredMarginSize
visible: Qt.platform.os == "windows" ? true : false visible: UpdateManager.isUpdaterEnabled()
} }
} }
} }
...@@ -50,7 +50,9 @@ ColumnLayout { ...@@ -50,7 +50,9 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: JamiTheme.preferredMarginSize Layout.leftMargin: JamiTheme.preferredMarginSize
checked: UtilsAdapter.getAppValue(Settings.Key.AutoUpdate) checked: Qt.platform.os.toString() === "windows" ?
UtilsAdapter.getAppValue(Settings.Key.AutoUpdate) :
UpdateManager.isAutoUpdaterEnabled()
labelText: JamiStrings.update labelText: JamiStrings.update
tooltipText: JamiStrings.enableAutoUpdates tooltipText: JamiStrings.enableAutoUpdates
...@@ -84,7 +86,7 @@ ColumnLayout { ...@@ -84,7 +86,7 @@ ColumnLayout {
MaterialButton { MaterialButton {
id: installBetaButton id: installBetaButton
visible: !UpdateManager.isCurrentVersionBeta() visible: !UpdateManager.isCurrentVersionBeta() && Qt.platform.os.toString() === "windows"
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
......
/*! /*
* Copyright (C) 2020-2022 Savoir-faire Linux Inc. * Copyright (C) 2020-2022 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* *
...@@ -38,11 +38,11 @@ static constexpr char betaVersionSubUrl[] = "/beta/version"; ...@@ -38,11 +38,11 @@ static constexpr char betaVersionSubUrl[] = "/beta/version";
static constexpr char msiSubUrl[] = "/jami.release.x64.msi"; static constexpr char msiSubUrl[] = "/jami.release.x64.msi";
static constexpr char betaMsiSubUrl[] = "/beta/jami.beta.x64.msi"; static constexpr char betaMsiSubUrl[] = "/beta/jami.beta.x64.msi";
UpdateManager::UpdateManager(const QString& url, struct UpdateManager::Impl : public QObject
ConnectivityMonitor* cm, {
LRCInstance* instance, Impl(const QString& url, ConnectivityMonitor* cm, LRCInstance* instance, UpdateManager& parent)
QObject* parent) : QObject(nullptr)
: NetWorkManager(cm, parent) , parent_(parent)
, lrcInstance_(instance) , lrcInstance_(instance)
, baseUrlString_(url.isEmpty() ? downloadUrl : url) , baseUrlString_(url.isEmpty() ? downloadUrl : url)
, tempPath_(Utils::WinGetEnv("TEMP")) , tempPath_(Utils::WinGetEnv("TEMP"))
...@@ -50,44 +50,29 @@ UpdateManager::UpdateManager(const QString& url, ...@@ -50,44 +50,29 @@ UpdateManager::UpdateManager(const QString& url,
{ {
connect(updateTimer_, &QTimer::timeout, [this] { connect(updateTimer_, &QTimer::timeout, [this] {
// Quiet period update check. // Quiet period update check.
checkForUpdates(true); parent_.checkForUpdates(true);
}); });
} };
~Impl() = default;
void
UpdateManager::setAutoUpdateCheck(bool state)
{
// Quiet check for updates periodically, if set to.
if (!state) {
updateTimer_->stop();
return;
}
updateTimer_->start(updatePeriod);
}
bool
UpdateManager::isCurrentVersionBeta()
{
return isBeta;
}
void void checkForUpdates(bool quiet)
UpdateManager::checkForUpdates(bool quiet)
{ {
disconnect(); parent_.disconnect();
// Fail without UI if this is a programmatic check. // Fail without UI if this is a programmatic check.
if (!quiet) if (!quiet)
connect(this, &NetWorkManager::errorOccured, this, &UpdateManager::updateCheckErrorOccurred); connect(&parent_,
&NetWorkManager::errorOccured,
&parent_,
&UpdateManager::updateCheckErrorOccurred);
cleanUpdateFiles(); cleanUpdateFiles();
QUrl versionUrl {isBeta ? QUrl::fromUserInput(baseUrlString_ + betaVersionSubUrl) QUrl versionUrl {isBeta ? QUrl::fromUserInput(baseUrlString_ + betaVersionSubUrl)
: QUrl::fromUserInput(baseUrlString_ + versionSubUrl)}; : QUrl::fromUserInput(baseUrlString_ + versionSubUrl)};
get(versionUrl, [this, quiet](const QString& latestVersionString) { parent_.get(versionUrl, [this, quiet](const QString& latestVersionString) {
if (latestVersionString.isEmpty()) { if (latestVersionString.isEmpty()) {
qWarning() << "Error checking version"; qWarning() << "Error checking version";
if (!quiet) if (!quiet)
Q_EMIT updateCheckReplyReceived(false); Q_EMIT parent_.updateCheckReplyReceived(false);
return; return;
} }
auto currentVersion = QString(VERSION_STRING).toULongLong(); auto currentVersion = QString(VERSION_STRING).toULongLong();
...@@ -95,31 +80,33 @@ UpdateManager::checkForUpdates(bool quiet) ...@@ -95,31 +80,33 @@ UpdateManager::checkForUpdates(bool quiet)
qDebug() << "latest: " << latestVersion << " current: " << currentVersion; qDebug() << "latest: " << latestVersion << " current: " << currentVersion;
if (latestVersion > currentVersion) { if (latestVersion > currentVersion) {
qDebug() << "New version found"; qDebug() << "New version found";
Q_EMIT updateCheckReplyReceived(true, true); Q_EMIT parent_.updateCheckReplyReceived(true, true);
} else { } else {
qDebug() << "No new version found"; qDebug() << "No new version found";
if (!quiet) if (!quiet)
Q_EMIT updateCheckReplyReceived(true, false); Q_EMIT parent_.updateCheckReplyReceived(true, false);
} }
}); });
} };
void void applyUpdates(bool beta = false)
UpdateManager::applyUpdates(bool beta)
{ {
disconnect(); parent_.disconnect();
connect(this, &NetWorkManager::errorOccured, this, &UpdateManager::updateDownloadErrorOccurred); connect(&parent_,
connect(this, &NetWorkManager::statusChanged, [this](GetStatus status) { &NetWorkManager::errorOccured,
&parent_,
&UpdateManager::updateDownloadErrorOccurred);
connect(&parent_, &NetWorkManager::statusChanged, [this](GetStatus status) {
switch (status) { switch (status) {
case GetStatus::STARTED: case GetStatus::STARTED:
connect(this, connect(&parent_,
&NetWorkManager::downloadProgressChanged, &NetWorkManager::downloadProgressChanged,
this, &parent_,
&UpdateManager::updateDownloadProgressChanged); &UpdateManager::updateDownloadProgressChanged);
Q_EMIT updateDownloadStarted(); Q_EMIT parent_.updateDownloadStarted();
break; break;
case GetStatus::FINISHED: case GetStatus::FINISHED:
Q_EMIT updateDownloadFinished(); Q_EMIT parent_.updateDownloadFinished();
break; break;
default: default:
break; break;
...@@ -129,7 +116,7 @@ UpdateManager::applyUpdates(bool beta) ...@@ -129,7 +116,7 @@ UpdateManager::applyUpdates(bool beta)
QUrl downloadUrl {(beta || isBeta) ? QUrl::fromUserInput(baseUrlString_ + betaMsiSubUrl) QUrl downloadUrl {(beta || isBeta) ? QUrl::fromUserInput(baseUrlString_ + betaMsiSubUrl)
: QUrl::fromUserInput(baseUrlString_ + msiSubUrl)}; : QUrl::fromUserInput(baseUrlString_ + msiSubUrl)};
get( parent_.get(
downloadUrl, downloadUrl,
[this, downloadUrl](const QString&) { [this, downloadUrl](const QString&) {
lrcInstance_->finish(); lrcInstance_->finish();
...@@ -142,20 +129,26 @@ UpdateManager::applyUpdates(bool beta) ...@@ -142,20 +129,26 @@ UpdateManager::applyUpdates(bool beta)
process.waitForFinished(); process.waitForFinished();
}, },
tempPath_); tempPath_);
} };
void void cancelUpdate()
UpdateManager::cancelUpdate() {
parent_.cancelRequest();
};
void setAutoUpdateCheck(bool state)
{ {
cancelRequest(); // Quiet check for updates periodically, if set to.
if (!state) {
updateTimer_->stop();
return;
} }
updateTimer_->start(updatePeriod);
};
void void cleanUpdateFiles()
UpdateManager::cleanUpdateFiles()
{ {
/* // Delete all logs and msi in the %TEMP% directory before launching.
* Delete all logs and msi in the %TEMP% directory before launching.
*/
QString dir = QString(Utils::WinGetEnv("TEMP")); QString dir = QString(Utils::WinGetEnv("TEMP"));
QDir log_dir(dir, {"jami*.log"}); QDir log_dir(dir, {"jami*.log"});
for (const QString& filename : log_dir.entryList()) { for (const QString& filename : log_dir.entryList()) {
...@@ -169,4 +162,67 @@ UpdateManager::cleanUpdateFiles() ...@@ -169,4 +162,67 @@ UpdateManager::cleanUpdateFiles()
for (const QString& filename : version_dir.entryList()) { for (const QString& filename : version_dir.entryList()) {
version_dir.remove(filename); version_dir.remove(filename);
} }
};
UpdateManager& parent_;
LRCInstance* lrcInstance_ {nullptr};
QString baseUrlString_;
QString tempPath_;
QTimer* updateTimer_;
};
UpdateManager::UpdateManager(const QString& url,
ConnectivityMonitor* cm,
LRCInstance* instance,
QObject* parent)
: NetWorkManager(cm, parent)
, pimpl_(std::make_unique<Impl>(url, cm, instance, *this))
{}
UpdateManager::~UpdateManager() {}
void
UpdateManager::checkForUpdates(bool quiet)
{
pimpl_->checkForUpdates(quiet);
}
void
UpdateManager::applyUpdates(bool beta)
{
pimpl_->applyUpdates(beta);
}
void
UpdateManager::cancelUpdate()
{
pimpl_->cancelUpdate();
}
void
UpdateManager::setAutoUpdateCheck(bool state)
{
pimpl_->setAutoUpdateCheck(state);
}
bool
UpdateManager::isCurrentVersionBeta()
{
return isBeta;
}
bool
UpdateManager::isUpdaterEnabled()
{
#ifdef Q_OS_WIN
return true;
#endif
return false;
}
bool
UpdateManager::isAutoUpdaterEnabled()
{
return false;
} }
/*! /*
* Copyright (C) 2020-2022 Savoir-faire Linux Inc. * Copyright (C) 2020-2022 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com> * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* *
...@@ -20,25 +20,29 @@ ...@@ -20,25 +20,29 @@
#include "networkmanager.h" #include "networkmanager.h"
#include <memory>
class LRCInstance; class LRCInstance;
class ConnectivityMonitor; class ConnectivityMonitor;
class QTimer;
class UpdateManager final : public NetWorkManager class UpdateManager final : public NetWorkManager
{ {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(UpdateManager)
public: public:
explicit UpdateManager(const QString& url, explicit UpdateManager(const QString& url,
ConnectivityMonitor* cm, ConnectivityMonitor* cm,
LRCInstance* instance = nullptr, LRCInstance* instance = nullptr,
QObject* parent = nullptr); QObject* parent = nullptr);
~UpdateManager() = default; ~UpdateManager();
Q_INVOKABLE void checkForUpdates(bool quiet = false); Q_INVOKABLE void checkForUpdates(bool quiet = false);
Q_INVOKABLE void applyUpdates(bool beta = false); Q_INVOKABLE void applyUpdates(bool beta = false);
Q_INVOKABLE void cancelUpdate(); Q_INVOKABLE void cancelUpdate();
Q_INVOKABLE void setAutoUpdateCheck(bool state); Q_INVOKABLE void setAutoUpdateCheck(bool state);
Q_INVOKABLE bool isCurrentVersionBeta(); Q_INVOKABLE bool isCurrentVersionBeta();
Q_INVOKABLE bool isUpdaterEnabled();
Q_INVOKABLE bool isAutoUpdaterEnabled();
Q_SIGNALS: Q_SIGNALS:
void updateCheckReplyReceived(bool ok, bool found = false); void updateCheckReplyReceived(bool ok, bool found = false);
...@@ -50,13 +54,7 @@ Q_SIGNALS: ...@@ -50,13 +54,7 @@ Q_SIGNALS:
void appCloseRequested(); void appCloseRequested();
private: private:
// LRCInstance pointer struct Impl;
LRCInstance* lrcInstance_ {nullptr}; std::unique_ptr<Impl> pimpl_;
QString baseUrlString_;
QString tempPath_;
QTimer* updateTimer_;
void cleanUpdateFiles();
}; };
Q_DECLARE_METATYPE(UpdateManager*) Q_DECLARE_METATYPE(UpdateManager*)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment