diff --git a/CMakeLists.txt b/CMakeLists.txt index cea545178..8208c0900 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ if(isMultiConfig) endif() endif() -project(AusweisApp VERSION 2.2.0 LANGUAGES ${LANGUAGES}) +project(AusweisApp VERSION 2.2.1 LANGUAGES ${LANGUAGES}) if(ANDROID AND NOT GOVERNIKUS_TOOLCHAIN_FILE) message(FATAL_ERROR "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_DIR}/android.toolchain.cmake is required") diff --git a/Dockerfile b/Dockerfile index 1721cf6de..24da7ebd7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -61,4 +61,4 @@ USER ausweisapp VOLUME ["/home/ausweisapp/.config"] ENTRYPOINT ["/sbin/tini", "--"] EXPOSE 24727 -CMD ["AusweisApp", "--address", "0.0.0.0"] +CMD ["AusweisApp", "--address", "0.0.0.0", "--no-logfile"] diff --git a/LICENSE.officially.txt b/LICENSE.officially.txt index eea49d584..caf1ed6d4 100644 --- a/LICENSE.officially.txt +++ b/LICENSE.officially.txt @@ -350,7 +350,7 @@ Die verwendeten Open-Source-Bibliotheken unterliegen den folgenden Nutzungsbedin OpenSSL Lizenz: Apache 2.0 - Version: 3.3.1 + Version: 3.3.2 Adresse: https://www.openssl.org/ Qt diff --git a/LICENSE.txt b/LICENSE.txt index 81355c050..dec10380c 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -318,7 +318,7 @@ Die verwendeten Open-Source-Bibliotheken unterliegen den folgenden Nutzungsbedin OpenSSL Lizenz: Apache 2.0 - Version: 3.3.1 + Version: 3.3.2 Adresse: https://www.openssl.org/ Qt diff --git a/cmake/CompilerFlags.cmake b/cmake/CompilerFlags.cmake index 5eb53649f..704b2a1d3 100644 --- a/cmake/CompilerFlags.cmake +++ b/cmake/CompilerFlags.cmake @@ -129,6 +129,11 @@ else() if(ANDROID) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--gc-sections -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now") + if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a" OR CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64") + set(ANDROID_PAGE_SIZE_FLAGS "-Wl,-z,max-page-size=16384") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${ANDROID_PAGE_SIZE_FLAGS}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${ANDROID_PAGE_SIZE_FLAGS}") + endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections") if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finline-limit=64") diff --git a/cmake/Helper.cmake b/cmake/Helper.cmake index 371549ffd..e0c33a5d9 100644 --- a/cmake/Helper.cmake +++ b/cmake/Helper.cmake @@ -13,7 +13,7 @@ include(CheckCXXCompilerFlag) # group multiple flags or to indicate the usage. # LINK: Use these linker flags to try the compiler flag. The linker # flags won't be added unless LINK_GLOBAL is enabled. Otherwise they are for testing only. -# LINK_VAR: Checked link flags will be added to these variables. (default: CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS) +# LINK_VAR: Checked link flags will be added to these variables. (default: CMAKE_EXE_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS CMAKE_MODULE_LINKER_FLAGS) # VAR: Checked compiler flags will be added to these variables. (default: CMAKE_CXX_FLAGS) # It is possible to add multiple VAR parameter. # If VAR parameter is a cmake TARGET the compiler flag will be added diff --git a/cmake/Packaging.android.cmake b/cmake/Packaging.android.cmake index 3d5d4d712..9351f24c0 100644 --- a/cmake/Packaging.android.cmake +++ b/cmake/Packaging.android.cmake @@ -12,12 +12,12 @@ endif() if(INTEGRATED_SDK) set(ANDROID_MANIFEST AndroidManifest.xml.aar.in) - set(JAVA_FILES network/WifiInfo* ui/aidl/AidlBinder* android/LogHandler* android/BootstrapHelper* android/AusweisApp2Service* android/AusweisApp2LocalIfdServiceConnection*) - configure_files("${SRC_DIR}" "${JAVA_FILES}" "${ANDROID_PACKAGE_SRC_DIR}/src" FLATTEN) + set(JAVA_FILES network/WifiInfo.java ui/aidl/AidlBinder.java android/LogHandler.java android/BootstrapHelper.java android/AusweisApp2Service.java android/AusweisApp2LocalIfdServiceConnection.java) configure_file(${PACKAGING_DIR}/android/res/values/strings.xml ${ANDROID_PACKAGE_SRC_DIR}/res/values/strings.xml COPYONLY) else() set(ANDROID_MANIFEST AndroidManifest.xml.apk.in) + set(JAVA_FILES *.java) if(USE_SMARTEID) set(LOCAL_IFD_SERVICE_ENABLED true) @@ -33,9 +33,9 @@ else() endforeach() configure_files("${PACKAGING_DIR}/android" "res/*" "${ANDROID_PACKAGE_SRC_DIR}") - configure_files("${SRC_DIR}" "*.java" "${ANDROID_PACKAGE_SRC_DIR}/src" FLATTEN) endif() +configure_files(${SRC_DIR} "${JAVA_FILES}" ${ANDROID_PACKAGE_SRC_DIR}/src/com/governikus/ausweisapp2 FLATTEN) configure_file(${PACKAGING_DIR}/android/IAusweisApp2Sdk.aidl ${ANDROID_PACKAGE_SRC_DIR}/src/com/governikus/ausweisapp2/IAusweisApp2Sdk.aidl COPYONLY) configure_file(${PACKAGING_DIR}/android/IAusweisApp2SdkCallback.aidl ${ANDROID_PACKAGE_SRC_DIR}/src/com/governikus/ausweisapp2/IAusweisApp2SdkCallback.aidl COPYONLY) @@ -102,7 +102,11 @@ if(INTEGRATED_SDK) configure_file("${PACKAGING_DIR}/android/consumer-rules.pro" "${ANDROID_BUILD_DIR}/consumer-rules.pro" COPYONLY) else() set(ANDROID_FILE_EXT apk) - configure_file("${PACKAGING_DIR}/android/lint.apk.xml" "${ANDROID_BUILD_DIR}/lint.xml" COPYONLY) + if(USE_SMARTEID) + configure_file("${PACKAGING_DIR}/android/lint.apk.smarteid.xml" "${ANDROID_BUILD_DIR}/lint.xml" COPYONLY) + else() + configure_file("${PACKAGING_DIR}/android/lint.apk.xml" "${ANDROID_BUILD_DIR}/lint.xml" COPYONLY) + endif() endif() configure_file(${PACKAGING_DIR}/android/gradle.properties.in ${ANDROID_BUILD_DIR}/gradle.properties @ONLY) @@ -114,6 +118,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "DEBUG") else() set(ANDROID_FILE ${ANDROID_BUILD_NAME}-debug.${ANDROID_FILE_EXT}) endif() + set(ANDROID_FILE_AAB ${ANDROID_BUILD_NAME}-debug.aab) else() if(INTEGRATED_SDK) set(DEPLOY_CMD_SIGN --release) @@ -125,19 +130,26 @@ else() set(ANDROID_FILE ${ANDROID_BUILD_NAME}-release-unsigned.apk) message(WARNING "Cannot sign release build! Set environment like QT_ANDROID_KEYSTORE_PATH") endif() + set(ANDROID_FILE_AAB ${ANDROID_BUILD_NAME}-release.aab) endif() -set(SOURCE_ANDROID_FILE ${ANDROID_BUILD_DIR}/build/outputs/${ANDROID_FILE_EXT}) +set(SOURCE_ANDROID_FILE_OUTPUT ${ANDROID_BUILD_DIR}/build/outputs) +set(SOURCE_ANDROID_FILE ${SOURCE_ANDROID_FILE_OUTPUT}/${ANDROID_FILE_EXT}) if(NOT INTEGRATED_SDK) + set(SOURCE_ANDROID_FILE_AAB ${SOURCE_ANDROID_FILE_OUTPUT}/bundle) if(CMAKE_BUILD_TYPE STREQUAL "DEBUG") set(SOURCE_ANDROID_FILE ${SOURCE_ANDROID_FILE}/debug) + set(SOURCE_ANDROID_FILE_AAB ${SOURCE_ANDROID_FILE_AAB}/debug) else() set(SOURCE_ANDROID_FILE ${SOURCE_ANDROID_FILE}/release) + set(SOURCE_ANDROID_FILE_AAB ${SOURCE_ANDROID_FILE_AAB}/release) endif() endif() set(SOURCE_ANDROID_FILE ${SOURCE_ANDROID_FILE}/${ANDROID_FILE}) +set(SOURCE_ANDROID_FILE_AAB ${SOURCE_ANDROID_FILE_AAB}/${ANDROID_FILE_AAB}) -set(DESTINATION_ANDROID_FILE ${PROJECT_BINARY_DIR}/dist/${CPACK_PACKAGE_FILE_NAME}.${ANDROID_FILE_EXT}) +set(DESTINATION_ANDROID_FILE_BASE ${PROJECT_BINARY_DIR}/dist/${CPACK_PACKAGE_FILE_NAME}) +set(DESTINATION_ANDROID_FILE ${DESTINATION_ANDROID_FILE_BASE}.${ANDROID_FILE_EXT}) if(INTEGRATED_SDK) find_program(androiddeployqt androiddeployqt HINTS "${QT_HOST_PATH}/bin" CMAKE_FIND_ROOT_PATH_BOTH) if(NOT androiddeployqt) @@ -149,12 +161,29 @@ if(INTEGRATED_SDK) COMMAND ${DEPLOY_CMD} DEPENDS AusweisAppBinary USES_TERMINAL) + + add_custom_command(TARGET ${ANDROID_FILE_EXT} POST_BUILD + COMMAND ${ANDROID_BUILD_DIR}/gradlew sourcesJar + COMMAND ${CMAKE_COMMAND} -E copy_if_different "build/libs/${ANDROID_BUILD_NAME}-sources.jar" "${PROJECT_BINARY_DIR}/dist/${CPACK_PACKAGE_FILE_NAME}-sources.jar" + WORKING_DIRECTORY ${ANDROID_BUILD_DIR} + USES_TERMINAL) +else() + add_custom_command(TARGET aab POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SOURCE_ANDROID_FILE_AAB}" "${DESTINATION_ANDROID_FILE_BASE}.aab" + WORKING_DIRECTORY ${ANDROID_BUILD_DIR} + USES_TERMINAL) + + if(QT_ANDROID_SIGN_APK) + add_custom_command(TARGET apk POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SOURCE_ANDROID_FILE}.idsig" "${DESTINATION_ANDROID_FILE}.idsig" + WORKING_DIRECTORY ${ANDROID_BUILD_DIR} + USES_TERMINAL) + endif() endif() add_custom_command(TARGET ${ANDROID_FILE_EXT} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SOURCE_ANDROID_FILE}" "${DESTINATION_ANDROID_FILE}" - COMMAND ${ANDROID_BUILD_DIR}/gradlew sourcesJar lint - COMMAND ${CMAKE_COMMAND} -E copy_if_different "build/libs/${ANDROID_BUILD_NAME}-sources.jar" "${PROJECT_BINARY_DIR}/dist/${CPACK_PACKAGE_FILE_NAME}-sources.jar" + COMMAND ${ANDROID_BUILD_DIR}/gradlew lint WORKING_DIRECTORY ${ANDROID_BUILD_DIR} USES_TERMINAL) @@ -165,7 +194,10 @@ if(INTEGRATED_SDK) else() find_program(apksigner apksigner HINTS ${ANDROID_SDK_ROOT}/build-tools/${ANDROID_BUILD_TOOLS_REVISION} CMAKE_FIND_ROOT_PATH_BOTH) if(apksigner) - add_custom_target(verify.signature COMMAND ${apksigner} verify --verbose --print-certs -Werr ${DESTINATION_ANDROID_FILE}) + if(QT_ANDROID_SIGN_APK) + set(APKSIGNER_PARAM -v4-signature-file ${DESTINATION_ANDROID_FILE}.idsig) + endif() + add_custom_target(verify.signature COMMAND ${apksigner} verify --verbose --print-certs -Werr ${APKSIGNER_PARAM} ${DESTINATION_ANDROID_FILE}) endif() find_program(aapt NAMES aapt2 aapt HINTS ${ANDROID_SDK_ROOT}/build-tools/${ANDROID_BUILD_TOOLS_REVISION} CMAKE_FIND_ROOT_PATH_BOTH) diff --git a/cmake/android.toolchain.cmake b/cmake/android.toolchain.cmake index 21358e816..dda2b8296 100644 --- a/cmake/android.toolchain.cmake +++ b/cmake/android.toolchain.cmake @@ -70,12 +70,13 @@ set(QT_ENABLE_VERBOSE_DEPLOYMENT ON) if(DEFINED ENV{QT_ANDROID_KEYSTORE_PATH} AND NOT INTEGRATED_SDK) set(QT_ANDROID_SIGN_APK ON) + set(QT_ANDROID_SIGN_AAB ON) endif() set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang) set(CMAKE_SYSTEM_NAME Android) set(CMAKE_SYSTEM_VERSION 28) -set(ANDROID_TARGET_SDK_VERSION 34) +set(ANDROID_TARGET_SDK_VERSION 35) set(CMAKE_ANDROID_STL_TYPE c++_shared) if(NOT CMAKE_ANDROID_ARCH_ABI) @@ -86,6 +87,16 @@ if(NOT CMAKE_ANDROID_ARCH_ABI) endif() endif() +# Only required by CMake < 3.30.3 with Android NDK 27 when +# CMAKE_ANDROID_ARCH_ABI is not set. Will be fixed with Android NDK 27b. +# https://bugreports.qt.io/browse/QTBUG-127468 +if(ANDROID_NDK_REVISION VERSION_EQUAL "27.0.12077973" AND CMAKE_VERSION VERSION_LESS "3.30.3") + set(NDK_PROC_aarch64_ABI "DUMMY") + set(NDK_PROC_armv7-a_ABI "DUMMY") + set(NDK_PROC_i686_ABI "DUMMY") + set(NDK_PROC_x86_64_ABI "DUMMY") +endif() + if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a") set(CMAKE_ANDROID_ARM_MODE ON) set(CMAKE_ANDROID_ARM_NEON ON) diff --git a/cmake/prepare_sonarqube_env.cmake b/cmake/prepare_sonarqube_env.cmake index 5ce9404d0..e7d7bc70b 100644 --- a/cmake/prepare_sonarqube_env.cmake +++ b/cmake/prepare_sonarqube_env.cmake @@ -13,20 +13,20 @@ message(STATUS "Use PACKAGES_DIR: ${PACKAGES_DIR}") set(BUILDWRAPPER_ZIP_NAME build-wrapper-linux-x86.zip) set(BUILDWRAPPER_URL https://sonar.govkg.de/static/cpp/${BUILDWRAPPER_ZIP_NAME}) -set(SONARSCANNERCLI_VERSION 5.0.1.3006-linux) # https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/ +set(SONARSCANNERCLI_VERSION 6.1.0.4477-linux-x64) # https://binaries.sonarsource.com/?prefix=Distribution/sonar-scanner-cli/ set(SONARSCANNERCLI_ZIP_NAME sonar-scanner-cli-${SONARSCANNERCLI_VERSION}.zip) set(SONARSCANNERCLI_URL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/${SONARSCANNERCLI_ZIP_NAME}) -set(SONARSCANNERCLI_HASH 350dbdb517c10fcb3ce70425db95c415b313cad7296c407d416d88f3d50121f8) +set(SONARSCANNERCLI_HASH aa985eacaa4155a064647370b62fc82d1b0e06caf1d493e04c2389dd5ac74fcb) -set(DEPENDENCYCHECK_VERSION 8.4.0) # https://github.com/jeremylong/DependencyCheck/releases +set(DEPENDENCYCHECK_VERSION 10.0.3) # https://github.com/jeremylong/DependencyCheck/releases set(DEPENDENCYCHECK_ZIP_NAME dependency-check-${DEPENDENCYCHECK_VERSION}-release.zip) set(DEPENDENCYCHECK_URL https://github.com/jeremylong/DependencyCheck/releases/download/v${DEPENDENCYCHECK_VERSION}/${DEPENDENCYCHECK_ZIP_NAME}) -set(DEPENDENCYCHECK_HASH 937a6bf8ced9d8494767082c1f588f26ea379324cb089dabb045321e8b0ab01a) +set(DEPENDENCYCHECK_HASH 5263fbafb15010823364274b83e9a2219b654d00a557d92941c37736d4076ba4) -set(MARIADB_CONNECTOR_VERSION 3.2.0) +set(MARIADB_CONNECTOR_VERSION 3.4.1) set(MARIADB_CONNECTOR_ZIP_NAME mariadb-java-client-${MARIADB_CONNECTOR_VERSION}.jar) set(MARIADB_CONNECTOR_URL https://downloads.mariadb.com/Connectors/java/connector-java-${MARIADB_CONNECTOR_VERSION}/${MARIADB_CONNECTOR_ZIP_NAME}) -set(MARIADB_CONNECTOR_HASH adf9df10bc9b2a137def36d6a495812258f430d4a8f7946727c61558e6c73941) +set(MARIADB_CONNECTOR_HASH f60e4b282f1f4bdb74f0a26436ba7078a5e480b6f6702f6a7b45d9ba5e604a24) set(SONARQUBETOOLS_DIR ${CMAKE_BINARY_DIR}/sonarqubetools) diff --git a/docs/releasenotes/2.2.1.rst b/docs/releasenotes/2.2.1.rst new file mode 100644 index 000000000..4fd83acb0 --- /dev/null +++ b/docs/releasenotes/2.2.1.rst @@ -0,0 +1,33 @@ +AusweisApp 2.2.1 +^^^^^^^^^^^^^^^^ + +**Releasedatum:** 11. September 2024 + + +Anwender +"""""""" +- Visuelle Anpassungen und Optimierungen der grafischen Oberfläche. + +- Optimierung der Barrierearmut und Tastaturbedienbarkeit. + +- Verhinderung der Anzeige externer Inhalte in der grafischen Oberfläche. + +- Unterstützung von Smartphones mit Android 15, bei denen + eine optimierte Speicherverwaltung aktiviert wurde. + + +Entwickler +"""""""""" +- Unterstützung von 16 KB Page Sizes unter Android. + +- Stabilisierung des iOS SDK bei schnellen Neustarts. + +- Korrektur des Verhaltens bei der Verwendung von Qt 6.6.3. + +- Vermeidung einer Logdatei innerhalb des Containers im Container-SDK. + +- Aktualisierung vom Android NDK auf r27b (27.1.12297006). + +- Aktualisierung der Android SDK Platform auf Android 15 (API-Level 35). + +- Aktualisierung von OpenSSL auf die Version 3.3.2. diff --git a/docs/releasenotes/announce.rst b/docs/releasenotes/announce.rst index ef807fc86..22f435946 100644 --- a/docs/releasenotes/announce.rst +++ b/docs/releasenotes/announce.rst @@ -5,6 +5,8 @@ Mit der Version 2.3.0 der AusweisApp wird die Unterstützung folgender Systeme eingestellt. - macOS Monterey 12 +- iOS 14 +- iOS 15 Mit der Version 2.2.0 der AusweisApp wurde die Unterstützung diff --git a/docs/releasenotes/appcast.rst b/docs/releasenotes/appcast.rst index 89c378328..bcefbe3f8 100644 --- a/docs/releasenotes/appcast.rst +++ b/docs/releasenotes/appcast.rst @@ -4,6 +4,7 @@ Release Notes .. toctree:: :maxdepth: 1 + 2.2.1 2.2.0 announce issues diff --git a/docs/releasenotes/issues.rst b/docs/releasenotes/issues.rst index 8cd45a048..03f96bf85 100644 --- a/docs/releasenotes/issues.rst +++ b/docs/releasenotes/issues.rst @@ -54,8 +54,6 @@ Barrierearmut - Unter Android werden unsichtbare Inhalte vom Screenreader vorgelesen. -- Unter iOS kann der sichtbare Bereich vom Systemfokus abweichen. - - Die angeforderten Rechte während eines Ausweisvorgangs werden nicht optimal vom Screenreader ausgegeben. diff --git a/docs/releasenotes/versions.rst b/docs/releasenotes/versions.rst index 16be64c09..c7e6d0c36 100644 --- a/docs/releasenotes/versions.rst +++ b/docs/releasenotes/versions.rst @@ -6,6 +6,7 @@ Versionszweig 2.2 .. toctree:: :maxdepth: 1 + 2.2.1 2.2.0 diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index cdc3dcebe..9b4188642 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -135,7 +135,7 @@ if("${OPENSSL}" MATCHES "SNAP") list(APPEND OPENSSL_URLS ${OPENSSL_SOURCE}/snapshot/${OPENSSL_FILE}) else() string(SUBSTRING ${OPENSSL} 0 5 OPENSSL_SUBVERSION) - list(APPEND OPENSSL_URLS ${OPENSSL_SOURCE}/${OPENSSL_FILE}) + list(APPEND OPENSSL_URLS https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL}/${OPENSSL_FILE}) list(APPEND OPENSSL_URLS ${OPENSSL_SOURCE}/old/${OPENSSL_SUBVERSION}/${OPENSSL_FILE}) endif() @@ -150,7 +150,7 @@ list(APPEND ENABLED_TARGETS openssl) set(OPENSSL_CONFIGURE_FLAGS no-camellia no-bf no-aria no-seed no-poly1305 no-srp no-gost no-idea no-mdc2 no-rc2 no-rc4 no-rc5 no-srtp no-sm2 no-sm3 no-sm4) set(OPENSSL_CONFIGURE_FLAGS ${OPENSSL_CONFIGURE_FLAGS} no-ct no-dgram no-cast no-chacha no-blake2 no-rmd160 no-scrypt no-siphash no-whirlpool no-md4 no-des no-ec2m) set(OPENSSL_CONFIGURE_FLAGS ${OPENSSL_CONFIGURE_FLAGS} no-tls1 no-tls1-method no-tls1_1 no-tls1_1-method no-tls1_3 no-ssl3 no-ssl3-method no-dtls no-dtls1-method no-dtls1_2-method) -set(OPENSSL_CONFIGURE_FLAGS ${OPENSSL_CONFIGURE_FLAGS} no-deprecated no-engine no-async no-dso no-comp no-ts no-makedepend no-tests no-legacy shared) +set(OPENSSL_CONFIGURE_FLAGS ${OPENSSL_CONFIGURE_FLAGS} no-deprecated no-engine no-async no-dso no-comp no-ts no-makedepend no-tests no-legacy) if(${CMAKE_BUILD_TYPE} STREQUAL "DEBUG") set(OPENSSL_CONFIGURE_FLAGS --debug ${OPENSSL_CONFIGURE_FLAGS}) @@ -175,7 +175,7 @@ else() endif() if(IOS) - set(OPENSSL_CONFIGURE_FLAGS ${OPENSSL_CONFIGURE_FLAGS} no-asm) + set(OPENSSL_CONFIGURE_FLAGS ${OPENSSL_CONFIGURE_FLAGS} no-asm no-shared) if(CMAKE_OSX_SYSROOT MATCHES "iphonesimulator") set(OPENSSL_ARCH iossimulator-xcrun) if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64") @@ -183,7 +183,7 @@ if(IOS) endif() set(OPENSSL_COMPILER_FLAGS ${OPENSSL_COMPILER_FLAGS} -mios-simulator-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) else() - set(OPENSSL_ARCH ios64-cross) + set(OPENSSL_ARCH ios64-xcrun) string(REGEX REPLACE "/SDKs/.*" "" CROSS_TOP_DEV_ROOT "${CMAKE_OSX_SYSROOT}") set(OPENSSL_ENV CROSS_TOP=${CROSS_TOP_DEV_ROOT} CROSS_SDK=iPhoneOS.sdk) set(OPENSSL_COMPILER_FLAGS ${OPENSSL_COMPILER_FLAGS} -mios-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) @@ -232,12 +232,14 @@ elseif(ANDROID) elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64") set(OPENSSL_ARCH android-x86_64) set(OPENSSL_NDK_PREFIX x86_64) + ADD_FLAG(-Wl,-z,max-page-size=16384 NOQUOTES VAR OPENSSL_COMPILER_FLAGS USE_SAME_FOR_LINKER USE_LINKER_ONLY) elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86") set(OPENSSL_ARCH android-x86) set(OPENSSL_NDK_PREFIX i686) elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") set(OPENSSL_ARCH android-arm64) set(OPENSSL_NDK_PREFIX aarch64) + ADD_FLAG(-Wl,-z,max-page-size=16384 NOQUOTES VAR OPENSSL_COMPILER_FLAGS USE_SAME_FOR_LINKER USE_LINKER_ONLY) else() message(FATAL_ERROR "CMAKE_ANDROID_ARCH_ABI not supported by openssl: ${CMAKE_ANDROID_ARCH_ABI}") endif() @@ -452,8 +454,12 @@ elseif(ANDROID) # ANDROID_TARGET_SDK_VERSION cannot be passed here as Qt has it's own variable and uses the latest in "${ANDROID_SDK_ROOT}/platforms". # https://code.qt.io/cgit/qt/qtbase.git/tree/cmake/QtPlatformAndroid.cmake?h=6.4#n36 + set(ANDROID_PAGE_SIZE_FLAGS "-Wl,-z,max-page-size=16384") if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") set(QT_CONFIGURE_FLAGS ${QT_CONFIGURE_FLAGS} -no-use-gold-linker) + set(ADDITIONAL_QT_DEFINES ${ADDITIONAL_QT_DEFINES} -DCMAKE_SHARED_LINKER_FLAGS=${ANDROID_PAGE_SIZE_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS=${ANDROID_PAGE_SIZE_FLAGS}) + elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64") + set(ADDITIONAL_QT_DEFINES ${ADDITIONAL_QT_DEFINES} -DCMAKE_SHARED_LINKER_FLAGS=${ANDROID_PAGE_SIZE_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS=${ANDROID_PAGE_SIZE_FLAGS}) endif() elseif(BSD) set(QT_CONFIGURE_FLAGS ${QT_CONFIGURE_FLAGS} ${QT_CONFIGURE_FLAGS_OTHER} -no-libudev) diff --git a/libs/README.rst b/libs/README.rst index 1581b2661..97442200c 100644 --- a/libs/README.rst +++ b/libs/README.rst @@ -313,7 +313,7 @@ Komponenten vorhanden sein: - Android SDK (cmdline) mit gesetztem ANDROID_SDK_ROOT - - https://developer.android.com/studio#cmdline-tools + - https://developer.android.com/tools#tools-sdk - Getestet: 12.0 diff --git a/libs/Versions.cmake b/libs/Versions.cmake index 4467b330b..4a9f3e8d4 100644 --- a/libs/Versions.cmake +++ b/libs/Versions.cmake @@ -1,5 +1,5 @@ set(QT 6.7.2) set(QT_HASH 0aaea247db870193c260e8453ae692ca12abc1bd841faa1a6e6c99459968ca8a) -set(OPENSSL 3.3.1) -set(OPENSSL_HASH 777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e) +set(OPENSSL 3.3.2) +set(OPENSSL_HASH 2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281) diff --git a/libs/patches/openssl-0001-android-shlib_variant.patch b/libs/patches/openssl-0001-android-shlib_variant.patch index 3151fd338..8fb7511ca 100644 --- a/libs/patches/openssl-0001-android-shlib_variant.patch +++ b/libs/patches/openssl-0001-android-shlib_variant.patch @@ -1,4 +1,4 @@ -From 550be844ea2eae755ff693681c18c3394b2f8ad1 Mon Sep 17 00:00:00 2001 +From fec417d3241ec474e90a8eba23f91864eb0c8860 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Tue, 19 Jan 2021 17:07:51 +0100 Subject: android shlib_variant diff --git a/libs/patches/openssl-0002-Fix-SSL_select_next_proto.patch b/libs/patches/openssl-0002-Fix-SSL_select_next_proto.patch deleted file mode 100644 index 0edf1fdbd..000000000 --- a/libs/patches/openssl-0002-Fix-SSL_select_next_proto.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 9e26fbb33b28628e106c91c2ba7fde7545a4eb89 Mon Sep 17 00:00:00 2001 -From: Matt Caswell -Date: Fri, 31 May 2024 11:14:33 +0100 -Subject: Fix SSL_select_next_proto - -Ensure that the provided client list is non-NULL and starts with a valid -entry. When called from the ALPN callback the client list should already -have been validated by OpenSSL so this should not cause a problem. When -called from the NPN callback the client list is locally configured and -will not have already been validated. Therefore SSL_select_next_proto -should not assume that it is correctly formatted. - -We implement stricter checking of the client protocol list. We also do the -same for the server list while we are about it. - -CVE-2024-5535 - -Reviewed-by: Tomas Mraz -Reviewed-by: Neil Horman -(Merged from https://github.com/openssl/openssl/pull/24716) - -(cherry picked from commit 2ebbe2d7ca8551c4cb5fbb391ab9af411708090e) -(cherry picked from commit e86ac436f0bd54d4517745483e2315650fae7b2c) ---- - ssl/ssl_lib.c | 63 ++++++++++++++++++++++++++++++++------------------- - 1 file changed, 40 insertions(+), 23 deletions(-) - -diff --git x/ssl/ssl_lib.c y/ssl/ssl_lib.c -index 5ec6ac4b63dc582059ebe0297b0562226c35f311..4c20ac4bf1fe7a48a7c5ed99641b84e774f1efeb 100644 ---- x/ssl/ssl_lib.c -+++ y/ssl/ssl_lib.c -@@ -3530,37 +3530,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, - unsigned int server_len, - const unsigned char *client, unsigned int client_len) - { -- unsigned int i, j; -- const unsigned char *result; -- int status = OPENSSL_NPN_UNSUPPORTED; -+ PACKET cpkt, csubpkt, spkt, ssubpkt; -+ -+ if (!PACKET_buf_init(&cpkt, client, client_len) -+ || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt) -+ || PACKET_remaining(&csubpkt) == 0) { -+ *out = NULL; -+ *outlen = 0; -+ return OPENSSL_NPN_NO_OVERLAP; -+ } -+ -+ /* -+ * Set the default opportunistic protocol. Will be overwritten if we find -+ * a match. -+ */ -+ *out = (unsigned char *)PACKET_data(&csubpkt); -+ *outlen = (unsigned char)PACKET_remaining(&csubpkt); - - /* - * For each protocol in server preference order, see if we support it. - */ -- for (i = 0; i < server_len;) { -- for (j = 0; j < client_len;) { -- if (server[i] == client[j] && -- memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { -- /* We found a match */ -- result = &server[i]; -- status = OPENSSL_NPN_NEGOTIATED; -- goto found; -+ if (PACKET_buf_init(&spkt, server, server_len)) { -+ while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) { -+ if (PACKET_remaining(&ssubpkt) == 0) -+ continue; /* Invalid - ignore it */ -+ if (PACKET_buf_init(&cpkt, client, client_len)) { -+ while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) { -+ if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt), -+ PACKET_remaining(&ssubpkt))) { -+ /* We found a match */ -+ *out = (unsigned char *)PACKET_data(&ssubpkt); -+ *outlen = (unsigned char)PACKET_remaining(&ssubpkt); -+ return OPENSSL_NPN_NEGOTIATED; -+ } -+ } -+ /* Ignore spurious trailing bytes in the client list */ -+ } else { -+ /* This should never happen */ -+ return OPENSSL_NPN_NO_OVERLAP; - } -- j += client[j]; -- j++; - } -- i += server[i]; -- i++; -+ /* Ignore spurious trailing bytes in the server list */ - } - -- /* There's no overlap between our protocols and the server's list. */ -- result = client; -- status = OPENSSL_NPN_NO_OVERLAP; -- -- found: -- *out = (unsigned char *)result + 1; -- *outlen = result[0]; -- return status; -+ /* -+ * There's no overlap between our protocols and the server's list. We use -+ * the default opportunistic protocol selected earlier -+ */ -+ return OPENSSL_NPN_NO_OVERLAP; - } - - #ifndef OPENSSL_NO_NEXTPROTONEG diff --git a/libs/patches/qtbase-0012-Fix-an-evaluated-use-of-std-declval-in-qjnitypes.h.patch b/libs/patches/qtbase-0012-Fix-an-evaluated-use-of-std-declval-in-qjnitypes.h.patch new file mode 100644 index 000000000..bc6a4509f --- /dev/null +++ b/libs/patches/qtbase-0012-Fix-an-evaluated-use-of-std-declval-in-qjnitypes.h.patch @@ -0,0 +1,54 @@ +From 4792d096ce5b976107cea653aecfd00d77c5ba21 Mon Sep 17 00:00:00 2001 +From: Ville Voutilainen +Date: Sun, 18 Aug 2024 01:59:29 +0300 +Subject: Fix an evaluated use of std::declval in qjnitypes.h + +While other compilers don't seem to have trouble with this, the latest +NDK (27) compiler does. That compiler diagnoses the empty-pack case, even though in that case there is no actual use of declval, as the pack-expanded expression contains no use of declval. +For other compilers, that may work for functions that have no arguments, but will not work for any function that does have arguments; in that case, the attempt to use declval will always be ill-formed, and there will be an attempt to use declval. + +The fix is straightforward; we have a Ret(*)(Args...), its return type +is simply Ret. So use a simple trait instead of the result of a call. + +Task-number: QTBUG-127468 +Change-Id: I0dc9e1201914ab94acc2940870be7c6d8cb16c12 +Pick-to: 6.8 6.7 +Reviewed-by: Thiago Macieira +(cherry picked from commit 236c6ec6f4c777d0534539f1c293cfc74006a6eb) +--- + src/corelib/kernel/qjnitypes.h | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git x/qtbase/src/corelib/kernel/qjnitypes.h y/qtbase/src/corelib/kernel/qjnitypes.h +index 4317f75fdba76abbd671e37ad434a4cf4e0c95f5..5e0754714b7936297d58c65cc03d1cc6664d35a9 100644 +--- x/qtbase/src/corelib/kernel/qjnitypes.h ++++ y/qtbase/src/corelib/kernel/qjnitypes.h +@@ -123,12 +123,14 @@ static constexpr auto makeTupleFromArgs(Ret (*)(JNIEnv *, jclass, Args...), va_l + return makeTupleFromArgsHelper(args); + } + +-// Get the return type of a function point +-template +-auto nativeFunctionReturnType(Ret(*function)(Args...)) ++template ++struct NativeFunctionReturnType {}; ++ ++template ++struct NativeFunctionReturnType + { +- return function(std::declval()...); +-} ++ using type = Ret; ++}; + + } // namespace Detail + } // namespace QtJniMethods +@@ -139,7 +141,7 @@ auto nativeFunctionReturnType(Ret(*function)(Args...)) + // the actual function with. This then takes care of implicit conversions, + // e.g. a jobject becomes a QJniObject. + #define Q_DECLARE_JNI_NATIVE_METHOD_HELPER(Method) \ +-static decltype(QtJniMethods::Detail::nativeFunctionReturnType(Method)) \ ++static QtJniMethods::Detail::NativeFunctionReturnType::type \ + va_##Method(JNIEnv *env, jclass thiz, ...) \ + { \ + va_list args; \ diff --git a/libs/patches/qtbase-0013-androiddeployqt-Fix-the-sign-argument-handling-order.patch b/libs/patches/qtbase-0013-androiddeployqt-Fix-the-sign-argument-handling-order.patch new file mode 100644 index 000000000..b60db2d7a --- /dev/null +++ b/libs/patches/qtbase-0013-androiddeployqt-Fix-the-sign-argument-handling-order.patch @@ -0,0 +1,53 @@ +From 50f8d79bd3d8753523512d187cb4b77fdaf8d000 Mon Sep 17 00:00:00 2001 +From: Alexey Edelev +Date: Wed, 21 Aug 2024 14:54:37 +0200 +Subject: androiddeployqt: Fix the --sign argument handling ordering + +Allow using the follow arguments after '--sign' argument in +androiddeployqt. The previous fix had no effect since we should +consider the argument count first and the type of arguments next. + +Amends 9c56a77027db2fedfc2b50f96ceaee5003a7d383 + +Fixes: QTBUG-128254 +Task-number: QTBUG-109619 +Pick-to: 6.5 6.7 6.8 +Change-Id: I34eac4def94c1d0c8d304f383d60c1e21b7dc6a2 +Reviewed-by: Assam Boudjelthia +(cherry picked from commit fd2c408af2f300e100d94a386743c7cbe74fadef) +--- + src/tools/androiddeployqt/main.cpp | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git x/qtbase/src/tools/androiddeployqt/main.cpp y/qtbase/src/tools/androiddeployqt/main.cpp +index d858bce1ce8516ae97accfafd4dd9fb3a9d30a99..72fa2a149698b5206492d4c15a369d02bbfd59b4 100644 +--- x/qtbase/src/tools/androiddeployqt/main.cpp ++++ y/qtbase/src/tools/androiddeployqt/main.cpp +@@ -444,7 +444,11 @@ Options parseOptions() + else + options.buildDirectory = arguments.at(++i); + } else if (argument.compare("--sign"_L1, Qt::CaseInsensitive) == 0) { +- if (i + 2 >= arguments.size()) { ++ if (i + 2 < arguments.size() && !arguments.at(i + 1).startsWith("--"_L1) && ++ !arguments.at(i + 2).startsWith("--"_L1)) { ++ options.keyStore = arguments.at(++i); ++ options.keyStoreAlias = arguments.at(++i); ++ } else { + const QString keyStore = qEnvironmentVariable("QT_ANDROID_KEYSTORE_PATH"); + const QString storeAlias = qEnvironmentVariable("QT_ANDROID_KEYSTORE_ALIAS"); + if (keyStore.isEmpty() || storeAlias.isEmpty()) { +@@ -457,14 +461,6 @@ Options parseOptions() + options.keyStore = keyStore; + options.keyStoreAlias = storeAlias; + } +- } else if (!arguments.at(i + 1).startsWith("--"_L1) && +- !arguments.at(i + 2).startsWith("--"_L1)) { +- options.keyStore = arguments.at(++i); +- options.keyStoreAlias = arguments.at(++i); +- } else { +- options.helpRequested = true; +- fprintf(stderr, "Package signing path and alias values are not " +- "specified.\n"); + } + + // Do not override if the passwords are provided through arguments diff --git a/libs/patches/qtbase-0014-Android-update-AGP-to-version-8.2.2.patch b/libs/patches/qtbase-0014-Android-update-AGP-to-version-8.2.2.patch new file mode 100644 index 000000000..4539d5b1f --- /dev/null +++ b/libs/patches/qtbase-0014-Android-update-AGP-to-version-8.2.2.patch @@ -0,0 +1,46 @@ +From 26743604b484cb338b15e2929de1b38ee813ad9d Mon Sep 17 00:00:00 2001 +From: Assam Boudjelthia +Date: Tue, 7 May 2024 15:59:21 +0300 +Subject: Android: update AGP to version 8.2.2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This works better with the current Gradle 8.3 and supports +Android api 34 builds. + +Task-number: QTBUG-106907 +Change-Id: I816a1aa163a9aee0a5859872129cff62f81a2dea +Reviewed-by: Tinja Paavoseppä +(cherry picked from commit 112e554cbf787fa6b093354d75889f520307c33e) +--- + doc/global/macros.qdocconf | 2 +- + src/android/templates/build.gradle | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git x/qtbase/doc/global/macros.qdocconf y/qtbase/doc/global/macros.qdocconf +index a4c38fa04255ec3ab43a843347ecc694b371adf2..a147be5653badd5924c8d475b7cc600035401605 100644 +--- x/qtbase/doc/global/macros.qdocconf ++++ y/qtbase/doc/global/macros.qdocconf +@@ -87,7 +87,7 @@ macro.AndroidMaxVer = "14" + macro.AndroidPlatformVer = "34" + macro.AndroidBuildToolsVer = "34.0.0" + macro.GradleVer = "8.3" +-macro.AGPVer = "7.4.1" ++macro.AGPVer = "8.2.2" + macro.AAOSVer = "10 to 13" + + macro.beginfloatleft.HTML = "
" +diff --git x/qtbase/src/android/templates/build.gradle y/qtbase/src/android/templates/build.gradle +index b03f36b136bed04fe38d0f376b62c4e9a1d1c123..e1f804dea7721f251f776ecb728eaac80f3b8745 100644 +--- x/qtbase/src/android/templates/build.gradle ++++ y/qtbase/src/android/templates/build.gradle +@@ -5,7 +5,7 @@ buildscript { + } + + dependencies { +- classpath 'com.android.tools.build:gradle:7.4.1' ++ classpath 'com.android.tools.build:gradle:8.2.2' + } + } + diff --git a/libs/patches/qtbase-0015-Android-Exclude-the-QtWindow-itself-from-Accessibilt.patch b/libs/patches/qtbase-0015-Android-Exclude-the-QtWindow-itself-from-Accessibilt.patch new file mode 100644 index 000000000..4cd37a8e2 --- /dev/null +++ b/libs/patches/qtbase-0015-Android-Exclude-the-QtWindow-itself-from-Accessibilt.patch @@ -0,0 +1,40 @@ +From 9cda8311d85365009c9523a5e56dc1e96d99146f Mon Sep 17 00:00:00 2001 +From: Julian Greilich +Date: Wed, 31 Jul 2024 14:01:41 +0200 +Subject: Android: Exclude the QtWindow itself from Accessibilty +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since the QtWindow and its QtEditText are focusable only to hand +over events to other components, the QtWindow itself should not be +focusable by TalkBack, since this leads to an unnecessary nameless A11y-Element +in the A11y tree. + +Task-number: QTBUG-126672 +Pick-to: 6.8 +Change-Id: I532b9d3e252fbe01da7c953446242b045c57eebe +Reviewed-by: Assam Boudjelthia +Reviewed-by: Jan Arve Sæther +(cherry-picked from 46cb9027f1ed6c61faec5364b5537ae7ab9e57c1) +--- + src/android/jar/src/org/qtproject/qt/android/QtWindow.java | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git x/qtbase/src/android/jar/src/org/qtproject/qt/android/QtWindow.java y/qtbase/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +index d72e69d32a73276e14a5fa725ed800a98a6be34f..816f52620c4d7b11d1bfeb6a287be3e337ccd24e 100644 +--- x/qtbase/src/android/jar/src/org/qtproject/qt/android/QtWindow.java ++++ y/qtbase/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +@@ -31,10 +31,12 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { + super(context); + setId(View.generateViewId()); + m_editText = new QtEditText(context, delegate); ++ m_editText.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + setParent(parentWindow); + setFocusableInTouchMode(true); + addView(m_editText, new QtLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); ++ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); + + QtNative.runAction(() -> { + m_gestureDetector = diff --git a/resources/jenkins/docker/Dockerfile b/resources/jenkins/docker/Dockerfile index d27bf31eb..6e8a94634 100644 --- a/resources/jenkins/docker/Dockerfile +++ b/resources/jenkins/docker/Dockerfile @@ -57,4 +57,4 @@ USER ausweisapp VOLUME ["/home/ausweisapp/.config"] ENTRYPOINT ["/sbin/tini", "--"] EXPOSE 5900/tcp 24727/tcp 24727/udp -CMD ["AusweisApp", "--address", "0.0.0.0"] +CMD ["AusweisApp", "--address", "0.0.0.0", "--no-logfile"] diff --git a/resources/jenkins/docker/ubuntu-android/Dockerfile b/resources/jenkins/docker/ubuntu-android/Dockerfile index b40ca6a13..b63621a86 100644 --- a/resources/jenkins/docker/ubuntu-android/Dockerfile +++ b/resources/jenkins/docker/ubuntu-android/Dockerfile @@ -2,8 +2,8 @@ FROM dev-docker.governikus.de/ausweisapp2/ubuntu:swarm MAINTAINER Governikus KG ARG ANDROID_CMDLINE_TOOLS=11076708 -ARG ANDROID_NDK_VERSION=26.2.11394342 -ARG CMAKE=3.28.3 +ARG ANDROID_NDK_VERSION=27.1.12297006 +ARG CMAKE=3.30.3 ENV NAME=Android LABELS="Android" PACKAGES_DIR=/home/governikus/packages ENV ANDROID_SDK_ROOT /opt/android-sdk @@ -18,7 +18,7 @@ RUN wget https://github.com/Kitware/CMake/releases/download/v$CMAKE/cmake-$CMAKE RUN mkdir -p /tmp/dl && cd /tmp/dl && wget -O sdk.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS}_latest.zip && \ unzip sdk.zip && \ - yes | /tmp/dl/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_SDK_ROOT "cmdline-tools;12.0" "build-tools;34.0.0" "platforms;android-34" "ndk;${ANDROID_NDK_VERSION}" && \ + yes | /tmp/dl/cmdline-tools/bin/sdkmanager --sdk_root=$ANDROID_SDK_ROOT "cmdline-tools;12.0" "build-tools;34.0.0" "platforms;android-35" "ndk;${ANDROID_NDK_VERSION}" && \ rm -rf /tmp/dl USER governikus diff --git a/resources/jenkins/dsl/Builds/Build_Android.groovy b/resources/jenkins/dsl/Builds/Build_Android.groovy index a2a5fa374..12b1f1bb4 100644 --- a/resources/jenkins/dsl/Builds/Build_Android.groovy +++ b/resources/jenkins/dsl/Builds/Build_Android.groovy @@ -10,7 +10,7 @@ def j = new Build name: 'Android_APK_' + ARCH, libraries: 'Android_' + ARCH, label: 'Android', - artifacts: 'build/dist/**/AusweisApp-*.apk*,build/src/libAusweisApp*' + artifacts: 'build/dist/**,build/src/libAusweisApp*' ).generate(this) @@ -66,7 +66,7 @@ def j = new Build name: 'Android_AAR', libraries: 'Android_' + ARCH, label: 'Android', - artifacts: 'build/dist/**/ausweisapp-*.aar,build/dist/**/ausweisapp-*.pom,build/dist/**/ausweisapp-*.jar,build/**/debug.symbols/*' + artifacts: 'build/dist/**,build/**/debug.symbols/*' ).generate(this) j.with diff --git a/resources/jenkins/dsl/Releases/Release_Android.groovy b/resources/jenkins/dsl/Releases/Release_Android.groovy index 4bbe60563..f7386b4e6 100644 --- a/resources/jenkins/dsl/Releases/Release_Android.groovy +++ b/resources/jenkins/dsl/Releases/Release_Android.groovy @@ -12,7 +12,7 @@ def j = new Release name: 'Android_APK_' + ARCH, libraries: 'Android_' + ARCH, label: 'Android', - artifacts: 'libs/Toolchain_*,build/dist/**/AusweisApp*.apk*,build/src/libAusweisApp*' + artifacts: 'libs/Toolchain_*,build/dist/**,build/src/libAusweisApp*' ).generate(this) @@ -46,7 +46,6 @@ j.with """)) shell('cmake --build build') - shell('cmake --install build') // remove this if 2.2.0 is stable shell('cmake --build build --target apk') shell('cmake --build build --target verify.signature') shell('cmake --build build --target dump.apk') @@ -65,7 +64,7 @@ def j = new Release name: 'Android_AAR', libraries: 'Android_' + ARCH, label: 'Android', - artifacts: 'libs/Toolchain_*,build/**/dist/**/ausweisapp-*.aar,build/**/dist/**/ausweisapp-*.pom,build/**/dist/**/ausweisapp-*.jar,build/**/debug.symbols/*' + artifacts: 'libs/Toolchain_*,build/dist/**,build/**/debug.symbols/*' ).generate(this) j.with @@ -85,7 +84,6 @@ j.with """)) shell('cmake --build build') - shell('cmake --install build') // remove this if 2.2.0 is stable shell('cmake --build build --target aar') shell("cd build/dist; cmake -DCMD=DEPLOY_NEXUS -P \$WORKSPACE/source/cmake/cmd.cmake") } diff --git a/resources/jenkins/dsl/Reviews/Review_Android.groovy b/resources/jenkins/dsl/Reviews/Review_Android.groovy index bacd89602..d45c60a17 100644 --- a/resources/jenkins/dsl/Reviews/Review_Android.groovy +++ b/resources/jenkins/dsl/Reviews/Review_Android.groovy @@ -10,7 +10,7 @@ def j = new Review name: 'Android_APK_' + ARCH, libraries: 'Android_' + ARCH, label: 'Android', - artifacts: 'build/dist/**/AusweisApp-*.apk*,build/src/libAusweisApp*' + artifacts: 'build/dist/**,build/src/libAusweisApp*' ).generate(this) @@ -58,7 +58,7 @@ def j = new Review name: 'Android_AAR', libraries: 'Android_' + ARCH, label: 'Android', - artifacts: 'build/dist/**/ausweisapp-*.aar,build/dist/**/ausweisapp-*.pom,build/dist/**/ausweisapp-*.jar,build/debug.symbols/*' + artifacts: 'build/dist/**,build/debug.symbols/*' ).generate(this) j.with diff --git a/resources/packaging/android/AndroidManifest.xml.apk.in b/resources/packaging/android/AndroidManifest.xml.apk.in index 749b71bab..d38f4c37a 100644 --- a/resources/packaging/android/AndroidManifest.xml.apk.in +++ b/resources/packaging/android/AndroidManifest.xml.apk.in @@ -75,7 +75,6 @@ android:exported="true" android:launchMode="singleTask" android:resizeableActivity="true" - android:screenOrientation="user" android:supportsPictureInPicture="true"> diff --git a/resources/packaging/android/build.gradle.append b/resources/packaging/android/build.gradle.append index dbdd7de53..cf700cac6 100644 --- a/resources/packaging/android/build.gradle.append +++ b/resources/packaging/android/build.gradle.append @@ -4,10 +4,6 @@ task sourcesJar(type: Jar) { archiveClassifier = "sources" } -dependencies { - implementation "androidx.core:core:1.13.1" -} - allprojects { repositories { maven { @@ -20,11 +16,7 @@ allprojects { } android { - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - + compileSdkVersion "android-35" packagingOptions { merges -= ['/META-INF/services/**'] exclude 'META-INF/proguard/androidx-annotations.pro' @@ -45,16 +37,17 @@ android { exclude '**/libplugins_imageformats_qtiff_*.so' exclude '**/libplugins_imageformats_qwebp_*.so' exclude '**/libplugins_imageformats_qwbmp_*.so' - - jniLibs { - useLegacyPackaging = true - } } lintOptions { lintConfig file('lint.xml') } + buildFeatures { + aidl = true + buildConfig = true + } + defaultConfig { buildConfigField("String", "ROOT_LOGGER", "\"${project.root_logger}\"") } diff --git a/resources/packaging/android/build.gradle.append.smarteid b/resources/packaging/android/build.gradle.append.smarteid index d445cb3be..3cc7d2a31 100644 --- a/resources/packaging/android/build.gradle.append.smarteid +++ b/resources/packaging/android/build.gradle.append.smarteid @@ -1,3 +1,3 @@ dependencies { - runtimeOnly "de.bundesdruckerei.android.eid-applet-service-lib:eid-applet-service-lib:1.1.0" + runtimeOnly "de.bundesdruckerei.android.eid-applet-service-lib:eid-applet-service-lib:1.2.0" } diff --git a/resources/packaging/android/lint.aar.xml b/resources/packaging/android/lint.aar.xml index 9611b4151..8bc2d4b59 100644 --- a/resources/packaging/android/lint.aar.xml +++ b/resources/packaging/android/lint.aar.xml @@ -19,12 +19,21 @@ --> - - - + + + + + diff --git a/resources/packaging/android/lint.apk.smarteid.xml b/resources/packaging/android/lint.apk.smarteid.xml new file mode 100644 index 000000000..3e0d4b110 --- /dev/null +++ b/resources/packaging/android/lint.apk.smarteid.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/packaging/android/lint.apk.xml b/resources/packaging/android/lint.apk.xml index 948f9f9f7..4b10dc209 100644 --- a/resources/packaging/android/lint.apk.xml +++ b/resources/packaging/android/lint.apk.xml @@ -12,21 +12,6 @@ - - - - - - - - - - - - - - + - - - + + diff --git a/resources/translations/ausweisapp_de.ts b/resources/translations/ausweisapp_de.ts index f220b009d..0331716eb 100644 --- a/resources/translations/ausweisapp_de.ts +++ b/resources/translations/ausweisapp_de.ts @@ -4,14 +4,14 @@ DvcsAttributes - 61757c650550 + 828ae9a4549a revision - 61757c650550 + 828ae9a4549a - 2.1.106 + 2.2.0 version - 2.1.106 + 2.2.0 @@ -510,11 +510,6 @@ LABEL ANDROID IOS - stellen Sie sicher, dass der Ausweis korrekt auf dem Kartenleser positioniert ist - bewegen Sie den Ausweis nicht, während auf diesen zugegriffen wird - - Change Transport PIN - LABEL ANDROID IOS - Transport-PIN ändern - The device "%1" was unpaired because it did not react to connection attempts. Pair the device again to use it as a card reader. INFO DESKTOP The paired devices was removed since it did not respond to connection attempts. It needs to be paired again if it should be used as card reader. @@ -2278,19 +2273,24 @@ LABEL ANDROID IOS Open %1 on your %2other device%3. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 3 + LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 4 Öffnen Sie auf Ihrem %2anderen Gerät%3 die %1. On that device go to %1Settings%2 and then %1Smartphone as card reader%2 resp. %1Manage pairings%2. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 3. %1 and %2 are surrounding tags for bold font. + LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 4. %1 and %2 are surrounding tags for bold font. Gehen Sie dort in die %1Einstellungen%2 und dann zu %1Smartphone als Kartenleser%2 bzw. %1Kopplungen verwalten%2. Choose this smartphone in the list to pair it. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 3 + LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 4 Wählen Sie in der angezeigten Liste dieses Smartphone aus, um es zu koppeln. + + Enter the pairing code "%1". + LABEL ANDROID IOS Provide pairing code. Step 4 of 4 + Geben Sie den Kopplungscode "%1" ein. + PairingFailedView @@ -2473,9 +2473,9 @@ INFO ALL_PLATFORMS Answer to the question 'How do I choose a secure (Smart- Die CAN ist eine 6-stellige Zahl, die %1unten rechts%2 auf der %1Vorderseite des Ausweisdokuments%2 zu finden ist. - The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in red). + The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in picture). INFO ALL_PLATFORMS Description text of CAN-allowed authentication - Die Zugangsnummer (CAN) ermöglicht den Zugriff auf die auf dem Ausweis gespeicherten Daten. Die CAN ist eine 6-stellige Zahl, die auf der Vorderseite des Ausweises unten rechts zu finden ist (rot markiert). + Die Zugangsnummer (CAN) ermöglicht den Zugriff auf die auf dem Ausweis gespeicherten Daten. Die CAN ist eine 6-stellige Zahl, die auf der Vorderseite des Ausweises unten rechts zu finden ist (auf Abbildung markiert). Smart-eID blocking code @@ -2652,7 +2652,7 @@ LABEL ALL_PLATFORMS If you applied for a %1PIN Reset letter%2, a new card PIN was already set for you. You can change your card PIN at %1any time in %3%2. INFO ALL_PLATFORMS Description text explaining the PINs (%1 is replaced with the application name) 7/7 - Falls Sie einen %1PIN-Rücksetzbrief%2 bestellt haben, wurde Ihen bereits eine Karten-PIN gesetzt. Sie können Ihre Karten-PIN jedoch %1jederzeit in der %3 ändern%2. + Falls Sie einen %1PIN-Rücksetzbrief%2 bestellt haben, wurde Ihnen bereits eine Karten-PIN gesetzt. Sie können Ihre Karten-PIN jedoch %1jederzeit in der %3 ändern%2. I can't recall my PIN @@ -3085,15 +3085,18 @@ LABEL ANDROID IOS RemoteReaderDelegate - Smartphone named "%1" - Smartphone namens "%1" + Smartphone named "%1". %2. + INFO DESKTOP Name and status of remote device. %1 is replaced with the name, %2 with the status + Smartphone namens "%1". %2. Press space to unpair the smartphone "%1". + INFO DESKTOP Text for activation action if the device is paired. Drücken Sie die Leertaste um das Smartphone "%1" zu entkoppeln. Press space to pair the smartphone "%1". + INFO DESKTOP Text for activation action if the device is unpaired. Drücken Sie die Leertaste um das Smartphone "%1" zu koppeln. @@ -3261,9 +3264,9 @@ Hierfür müssen Sie zuvor das entsprechende Gerät mit diesem Smartphone koppel Wo gebe ich den Kopplungscode ein? - Enter the pairing code %1 in the %2 on your other device. + Enter the pairing code "%1" in the %2 on your other device. INFO ANDROID IOS - Geben Sie den Kopplungscode %1 in der %2 auf Ihrem anderen Gerät ein. + Geben Sie den Kopplungscode "%1" in der %2 auf Ihrem anderen Gerät ein. Cancel pairing @@ -4223,12 +4226,13 @@ Um fortzufahren, verwenden Sie Ihren Ausweis, indem Sie die NFC-Schnittstelle au TabbedPane Tab selected + LABEL DESKTOP Registerkarte ausgewählt - You may navigate to different tabs by using the up/down arrows. - LABEL DESKTOP Additional description of TabbedPane behavior for a11y. - Sie können die verschiedenen Registerkarten mithilfe der Pfeiltasten auswählen. + %1 of %2 + LABEL DESKTOP %1 is the current selected Page of %2 Pages + %1 von %2 @@ -6353,11 +6357,6 @@ LABEL ALL_PLATFORMS Additional date format with unknown day governikus::StateConnectCard - - The used card reader does not meet the technical requirements (Extended Length not supported). - INFO IOS - Der verwendete Kartenleser erfüllt leider nicht die technischen Voraussetzungen (Extended Length wird nicht unterstützt). - The used ID card type is not accepted by the server. INFO IOS diff --git a/resources/translations/ausweisapp_ru.ts b/resources/translations/ausweisapp_ru.ts index 565995693..1dca6b345 100644 --- a/resources/translations/ausweisapp_ru.ts +++ b/resources/translations/ausweisapp_ru.ts @@ -4,14 +4,14 @@ DvcsAttributes - 61757c650550 + 828ae9a4549a revision - 61757c650550 + 828ae9a4549a - 2.1.106 + 2.2.0 version - 2.1.106 + 2.2.0 @@ -510,11 +510,6 @@ LABEL ANDROID IOS — Убедитесь в том, что карта правильно вставлена в устройство чтения карт — Не перемещайте карту, пока система получает к ней доступ - - Change Transport PIN - LABEL ANDROID IOS - Изменить временный PIN-код - The device "%1" was unpaired because it did not react to connection attempts. Pair the device again to use it as a card reader. INFO DESKTOP The paired devices was removed since it did not respond to connection attempts. It needs to be paired again if it should be used as card reader. @@ -2278,19 +2273,24 @@ LABEL ANDROID IOS Open %1 on your %2other device%3. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 3 + LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 4 Откройте %1 в другом %2вашем устройстве%3. On that device go to %1Settings%2 and then %1Smartphone as card reader%2 resp. %1Manage pairings%2. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 3. %1 and %2 are surrounding tags for bold font. + LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 4. %1 and %2 are surrounding tags for bold font. В данном устройстве перейдите в меню %1Настройки%2, а затем %1Смартфон в качестве устройства чтения карт%2 и в соответствующее меню %1Управлять сопряжениями%2. Choose this smartphone in the list to pair it. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 3 + LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 4 Чтобы выполнить сопряжение, выберите данный смартфон в списке. + + Enter the pairing code "%1". + LABEL ANDROID IOS Provide pairing code. Step 4 of 4 + + PairingFailedView @@ -2473,9 +2473,9 @@ INFO ALL_PLATFORMS Answer to the question 'How do I choose a secure (Smart- - The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in red). + The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in picture). INFO ALL_PLATFORMS Description text of CAN-allowed authentication - Код доступа (CAN) предоставляет доступ к сохраненным на идентификационной карте данным. CAN — это 6-значный номер, указанный на идентификационной карте спереди. Он расположен внизу справа рядом со сроком действия (выделен красным цветом). + Код доступа (CAN) предоставляет доступ к сохраненным на идентификационной карте данным. CAN — это 6-значный номер, указанный на идентификационной карте спереди. Он расположен внизу справа рядом со сроком действия (выделен красным цветом). Smart-eID blocking code @@ -3085,15 +3085,18 @@ LABEL ANDROID IOS RemoteReaderDelegate - Smartphone named "%1" - Имя смартфона «%1» + Smartphone named "%1". %2. + INFO DESKTOP Name and status of remote device. %1 is replaced with the name, %2 with the status + Имя смартфона «%1». %2. Press space to unpair the smartphone "%1". + INFO DESKTOP Text for activation action if the device is paired. Нажмите пробел, чтобы отменить сопряжение смартфона «%1». Press space to pair the smartphone "%1". + INFO DESKTOP Text for activation action if the device is unpaired. Нажмите пробел для сопряжения смартфона «%1». @@ -3261,9 +3264,9 @@ To do this you first have to pair that device with this smartphone. Где следует вводить код сопряжения? - Enter the pairing code %1 in the %2 on your other device. + Enter the pairing code "%1" in the %2 on your other device. INFO ANDROID IOS - Введите код сопряжения %1 в поле %2 в другом вашем устройстве. + Введите код сопряжения "%1" в поле %2 в другом вашем устройстве. Cancel pairing @@ -4223,12 +4226,13 @@ To proceed use your ID card by selecting the NFC interface. If you want to set u TabbedPane Tab selected + LABEL DESKTOP Вкладка выбрана - You may navigate to different tabs by using the up/down arrows. - LABEL DESKTOP Additional description of TabbedPane behavior for a11y. - Переключаться между вкладками можно с помощью стрелок вверх/вниз. + %1 of %2 + LABEL DESKTOP %1 is the current selected Page of %2 Pages + @@ -6353,11 +6357,6 @@ LABEL ALL_PLATFORMS Additional date format with unknown day governikus::StateConnectCard - - The used card reader does not meet the technical requirements (Extended Length not supported). - INFO IOS - Используемое устройство чтения карт не соответствует техническим требованиям (не поддерживается расширенная длина). - The used ID card type is not accepted by the server. INFO IOS diff --git a/resources/translations/ausweisapp_uk.ts b/resources/translations/ausweisapp_uk.ts index b8b6dc810..76e96794c 100644 --- a/resources/translations/ausweisapp_uk.ts +++ b/resources/translations/ausweisapp_uk.ts @@ -4,14 +4,14 @@ DvcsAttributes - 61757c650550 + 828ae9a4549a revision - 61757c650550 + 828ae9a4549a - 2.1.106 + 2.2.0 version - 2.1.106 + 2.2.0 @@ -510,11 +510,6 @@ LABEL ANDROID IOS - переконайтеся, що картку правильно розміщено на пристрої читання; - не переміщуйте картку, поки до неї здійснюється доступ - - Change Transport PIN - LABEL ANDROID IOS - Змінити транспортний PIN-код - The device "%1" was unpaired because it did not react to connection attempts. Pair the device again to use it as a card reader. INFO DESKTOP The paired devices was removed since it did not respond to connection attempts. It needs to be paired again if it should be used as card reader. @@ -2278,19 +2273,24 @@ LABEL ANDROID IOS Open %1 on your %2other device%3. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 3 + LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 4 Відкрийте %1 на своєму %2іншому пристрої%3. On that device go to %1Settings%2 and then %1Smartphone as card reader%2 resp. %1Manage pairings%2. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 3. %1 and %2 are surrounding tags for bold font. + LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 4. %1 and %2 are surrounding tags for bold font. Перейдіть на тому пристрої до розділу %1Параметри%2, а тоді виберіть %1Смартфон як пристрій читання карток%2 і %1Керування створенням пари%2. Choose this smartphone in the list to pair it. - LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 3 + LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 4 Виберіть цей смартфон у переліку, щоб створити з ним пару. + + Enter the pairing code "%1". + LABEL ANDROID IOS Provide pairing code. Step 4 of 4 + + PairingFailedView @@ -2473,9 +2473,9 @@ INFO ALL_PLATFORMS Answer to the question 'How do I choose a secure (Smart- - The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in red). + The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in picture). INFO ALL_PLATFORMS Description text of CAN-allowed authentication - Номер доступу до картки (CAN) дає змогу отримати доступ до вихідних даних ID-картки. CAN – це 6-значний номер, який можна знайти на лицьовій стороні ID-картки. Він розташований унизу праворуч від терміну дії (позначено червоним). + Номер доступу до картки (CAN) дає змогу отримати доступ до вихідних даних ID-картки. CAN – це 6-значний номер, який можна знайти на лицьовій стороні ID-картки. Він розташований унизу праворуч від терміну дії (позначено червоним). Smart-eID blocking code @@ -3085,15 +3085,18 @@ LABEL ANDROID IOS RemoteReaderDelegate - Smartphone named "%1" - Смартфон під іменем «%1» + Smartphone named "%1". %2. + INFO DESKTOP Name and status of remote device. %1 is replaced with the name, %2 with the status + Смартфон під іменем «%1». %2. Press space to unpair the smartphone "%1". + INFO DESKTOP Text for activation action if the device is paired. Натисніть пробіл, щоб скасувати пару зі смартфоном «%1». Press space to pair the smartphone "%1". + INFO DESKTOP Text for activation action if the device is unpaired. Натисніть пробіл, щоб створити пару зі смартфоном «%1». @@ -3261,9 +3264,9 @@ To do this you first have to pair that device with this smartphone. Куди вводити код створення пари? - Enter the pairing code %1 in the %2 on your other device. + Enter the pairing code "%1" in the %2 on your other device. INFO ANDROID IOS - Введіть код створення пари %1 у %2 на своєму іншому пристрої. + Введіть код створення пари "%1" у %2 на своєму іншому пристрої. Cancel pairing @@ -4223,12 +4226,13 @@ To proceed use your ID card by selecting the NFC interface. If you want to set u TabbedPane Tab selected + LABEL DESKTOP Вибрано вкладку - You may navigate to different tabs by using the up/down arrows. - LABEL DESKTOP Additional description of TabbedPane behavior for a11y. - Ви можете переходити до різних вкладок за допомогою стрілок вгору/вниз. + %1 of %2 + LABEL DESKTOP %1 is the current selected Page of %2 Pages + @@ -6353,11 +6357,6 @@ LABEL ALL_PLATFORMS Additional date format with unknown day governikus::StateConnectCard - - The used card reader does not meet the technical requirements (Extended Length not supported). - INFO IOS - Використовуваний пристрій читання карток не відповідає технічним вимогам (Extended Length не підтримується). - The used ID card type is not accepted by the server. INFO IOS diff --git a/resources/updatable-files/supported-providers.json b/resources/updatable-files/supported-providers.json index dbbb8a518..d74540403 100644 --- a/resources/updatable-files/supported-providers.json +++ b/resources/updatable-files/supported-providers.json @@ -139,7 +139,7 @@ "homepage": "https://www.bitkasten.de", "phone": "+49 911 6099 8688", "email": "nachricht@bitkasten.de", - "postalAddress": "bitkasten AG
Wallensteinstr. 63
90431 Nürnberg", + "postalAddress": "bitkasten GmbH
Wallensteinstr. 63
90431 Nürnberg", "image": "bitkasten_image.png", "icon": "bitkasten_icon.png", "category": "other", diff --git a/src/card/base/Card.cpp b/src/card/base/Card.cpp index 012ca25a4..bf439cac6 100644 --- a/src/card/base/Card.cpp +++ b/src/card/base/Card.cpp @@ -25,6 +25,12 @@ void Card::setProgressMessage(const QString& pMessage, int pProgress) } +void Card::setErrorMessage(const QString& pMessage) +{ + Q_UNUSED(pMessage) +} + + EstablishPaceChannelOutput Card::establishPaceChannel(PacePasswordId pPasswordId, int pPreferredPinLength, const QByteArray& pChat, const QByteArray& pCertificateDescription, quint8 pTimeoutSeconds) { Q_UNUSED(pPasswordId) @@ -74,6 +80,14 @@ QString Card::generateProgressMessage(const QString& pMessage, int pProgress) } +QString Card::generateErrorMessage(const QString& pMessage) +{ + return Env::getSingleton()->isUsedAsSDK() && !pMessage.isNull() + ? Env::getSingleton()->getMessages().getSessionFailed() + : pMessage; +} + + EstablishPaceChannelOutput Card::prepareIdentification(const QByteArray& pChat) { Q_UNUSED(pChat) diff --git a/src/card/base/Card.h b/src/card/base/Card.h index 5326a0790..e5fa8a83c 100644 --- a/src/card/base/Card.h +++ b/src/card/base/Card.h @@ -71,6 +71,7 @@ class Card * where interacting with a card leads to a dialog where the message needs to be updated. */ virtual void setProgressMessage(const QString& pMessage, int pProgress = -1); + virtual void setErrorMessage(const QString& pMessage); /*! * Performs a transmit to the smart card. @@ -98,6 +99,7 @@ class Card * Combines the message and progressvalue depending on the environment. */ static QString generateProgressMessage(const QString& pMessage, int pProgress = -1); + static QString generateErrorMessage(const QString& pMessage); virtual EstablishPaceChannelOutput prepareIdentification(const QByteArray& pChat); diff --git a/src/card/base/CardConnection.cpp b/src/card/base/CardConnection.cpp index ab80f23be..3ced3fa7b 100644 --- a/src/card/base/CardConnection.cpp +++ b/src/card/base/CardConnection.cpp @@ -64,6 +64,14 @@ void CardConnection::setProgressMessage(const QString& pMessage, int pProgress) } +void CardConnection::setErrorMessage(const QString& pMessage) +{ + QMetaObject::invokeMethod(mCardConnectionWorker.data(), [this, pMessage] { + mCardConnectionWorker->setErrorMessage(pMessage); + }, Qt::BlockingQueuedConnection); +} + + UpdateRetryCounterCommand* CardConnection::createUpdateRetryCounterCommand() { return new UpdateRetryCounterCommand(mCardConnectionWorker); diff --git a/src/card/base/CardConnection.h b/src/card/base/CardConnection.h index b0bfb9c42..488d32eb1 100644 --- a/src/card/base/CardConnection.h +++ b/src/card/base/CardConnection.h @@ -114,6 +114,7 @@ class CardConnection void setKeepAlive(bool pEnabled); void setProgressMessage(const QString& pMessage, int pProgress = -1); + void setErrorMessage(const QString& pMessage); template QMetaObject::Connection callDidAuthenticateEAC1Command(const typename QtPrivate::FunctionPointer::Object* pReceiver, T pFunc) diff --git a/src/card/base/CardConnectionWorker.cpp b/src/card/base/CardConnectionWorker.cpp index f1381191a..4bd274c16 100644 --- a/src/card/base/CardConnectionWorker.cpp +++ b/src/card/base/CardConnectionWorker.cpp @@ -280,6 +280,16 @@ void CardConnectionWorker::setProgressMessage(const QString& pMessage, int pProg } +void CardConnectionWorker::setErrorMessage(const QString& pMessage) +{ + const auto card = mReader ? mReader->getCard() : nullptr; + if (card) + { + card->setErrorMessage(pMessage); + } +} + + EstablishPaceChannelOutput CardConnectionWorker::establishPaceChannel(PacePasswordId pPasswordId, const QByteArray& pPasswordValue, const QByteArray& pChat, diff --git a/src/card/base/CardConnectionWorker.h b/src/card/base/CardConnectionWorker.h index 3850f8ea4..428696b8b 100644 --- a/src/card/base/CardConnectionWorker.h +++ b/src/card/base/CardConnectionWorker.h @@ -104,6 +104,7 @@ class CardConnectionWorker * where interacting with a card leads to a dialog where the message needs to be updated. */ virtual void setProgressMessage(const QString& pMessage, int pProgress = -1); + virtual void setErrorMessage(const QString& pMessage); virtual ResponseApduResult setEidPin(const QByteArray& pNewPin, quint8 pTimeoutSeconds); diff --git a/src/card/nfc/NfcCard.cpp b/src/card/nfc/NfcCard.cpp index dbaf3fc99..afb650137 100644 --- a/src/card/nfc/NfcCard.cpp +++ b/src/card/nfc/NfcCard.cpp @@ -90,6 +90,13 @@ void NfcCard::setProgressMessage(const QString& pMessage, int pProgress) } +void NfcCard::setErrorMessage(const QString& pMessage) +{ + QString message = generateErrorMessage(pMessage); + Q_EMIT fireSetProgressMessage(message); +} + + ResponseApduResult NfcCard::transmit(const CommandApdu& pCmd) { if (!mIsValid || mNearFieldTarget == nullptr) diff --git a/src/card/nfc/NfcCard.h b/src/card/nfc/NfcCard.h index ef05ea523..f69a6deef 100644 --- a/src/card/nfc/NfcCard.h +++ b/src/card/nfc/NfcCard.h @@ -36,6 +36,7 @@ class NfcCard CardReturnCode releaseConnection() override; bool isConnected() const override; void setProgressMessage(const QString& pMessage, int pProgress = -1) override; + void setErrorMessage(const QString& pMessage) override; ResponseApduResult transmit(const CommandApdu& pCmd) override; diff --git a/src/card/nfc/NfcReader.cpp b/src/card/nfc/NfcReader.cpp index 0850228f7..d0efc6af1 100644 --- a/src/card/nfc/NfcReader.cpp +++ b/src/card/nfc/NfcReader.cpp @@ -84,7 +84,7 @@ void NfcReader::targetDetected(QNearFieldTarget* pTarget) } const auto& info = Env::getSingleton()->isUsedAsSDK() - ? Env::getSingleton()->getMessages().getSessionInProgress() + ? Card::generateProgressMessage(QString(), 0) //: INFO IOS Feedback when a new ID card has been detected : tr("ID card detected. Please do not move the device!"); @@ -191,7 +191,7 @@ void NfcReader::disconnectReader(const QString& pError) : tr("Scanning process has been finished successfully."); mNfManager.setUserInformation(info); } - mNfManager.stopTargetDetection(pError); + mNfManager.stopTargetDetection(Card::generateErrorMessage(pError)); #else Q_UNUSED(pError) #endif diff --git a/src/ifd/base/IfdCard.cpp b/src/ifd/base/IfdCard.cpp index 69613dcb2..65b34ebf1 100644 --- a/src/ifd/base/IfdCard.cpp +++ b/src/ifd/base/IfdCard.cpp @@ -188,6 +188,12 @@ void IfdCard::setProgressMessage(const QString& pMessage, int pProgress) } +void IfdCard::setErrorMessage(const QString& pMessage) +{ + mProgressMessage = generateErrorMessage(pMessage); +} + + ResponseApduResult IfdCard::transmit(const CommandApdu& pCommand) { qCDebug(card_remote) << "Transmit command APDU:" << pCommand; diff --git a/src/ifd/base/IfdCard.h b/src/ifd/base/IfdCard.h index 76bfe53e3..330f552f4 100644 --- a/src/ifd/base/IfdCard.h +++ b/src/ifd/base/IfdCard.h @@ -57,6 +57,7 @@ class IfdCard CardReturnCode releaseConnection() override; bool isConnected() const override; void setProgressMessage(const QString& pMessage, int pProgress = -1) override; + void setErrorMessage(const QString& pMessage) override; ResponseApduResult transmit(const CommandApdu& pCmd) override; diff --git a/src/ifd/base/messages/Discovery.cpp b/src/ifd/base/messages/Discovery.cpp index 1058e6d17..739304ac7 100644 --- a/src/ifd/base/messages/Discovery.cpp +++ b/src/ifd/base/messages/Discovery.cpp @@ -82,7 +82,10 @@ void Discovery::parseIfdId(const QJsonObject& pMessageObject) if (!ifdCertificate.isNull()) { mIfdId = RemoteServiceSettings::generateFingerprint(ifdCertificate); + return; } + + mIfdId = mIfdId.toLower(); } @@ -108,7 +111,7 @@ void Discovery::parsePairing(const QJsonObject& pMessageObject) Discovery::Discovery(const QString& pIfdName, const QString& pIfdId, quint16 pPort, const QList& pSupportedApis, bool pPairing) : IfdMessage(IfdMessageType::UNDEFINED) - , mIfdName(pIfdName) + , mIfdName(pIfdName.toHtmlEscaped()) , mIfdId(pIfdId) , mPort(pPort) , mSupportedApis(pSupportedApis) @@ -131,7 +134,7 @@ Discovery::Discovery(const QJsonObject& pMessageObject) } parseSupportedApi(pMessageObject); - mIfdName = getStringValue(pMessageObject, IFD_NAME()); + mIfdName = getStringValue(pMessageObject, IFD_NAME()).toHtmlEscaped(); parseIfdId(pMessageObject); mPort = static_cast(getIntValue(pMessageObject, PORT(), 0)); parsePairing(pMessageObject); diff --git a/src/ui/functional/AusweisApp2.cpp b/src/ui/functional/AusweisApp2.cpp index a635b57ca..7c28fc704 100644 --- a/src/ui/functional/AusweisApp2.cpp +++ b/src/ui/functional/AusweisApp2.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -18,10 +20,11 @@ namespace { -static bool cInitialized = false; static bool cShutdownCalled = false; static AusweisApp2Callback cCallback = nullptr; static std::thread cThread; // clazy:exclude=non-pod-global-static +static std::future cStartedFuture; // clazy:exclude=non-pod-global-static +static std::promise cStartedPromise; // clazy:exclude=non-pod-global-static static std::mutex cMutex; } // namespace @@ -50,8 +53,7 @@ Q_DECL_EXPORT bool ausweisapp2_is_running_internal() Q_DECL_EXPORT void ausweisapp2_started_internal() { - const std::lock_guard lock(cMutex); - cInitialized = true; + cStartedPromise.set_value(); } @@ -105,6 +107,9 @@ Q_DECL_EXPORT bool ausweisapp2_init(AusweisApp2Callback pCallback, const char* p cCallback = pCallback; cShutdownCalled = false; + + cStartedPromise = std::promise(); + cStartedFuture = cStartedPromise.get_future(); cThread = std::thread(&ausweisapp2_init_internal, QByteArray(pCmdline)); return true; @@ -119,6 +124,9 @@ Q_DECL_EXPORT void ausweisapp2_shutdown(void) if (!cShutdownCalled) { cShutdownCalled = true; // do not request twice as the UiLoader could be re-spawned after shutdown! + + cStartedFuture.wait(); + std::cout << "Send shutdown request" << std::endl; QMetaObject::invokeMethod(QCoreApplication::instance(), [] { @@ -147,7 +155,9 @@ Q_DECL_EXPORT void ausweisapp2_send(const char* pCmd) { const std::lock_guard lock(cMutex); - if (cShutdownCalled || !cInitialized || pCmd == nullptr) + using namespace std::chrono_literals; + const bool initialized = cStartedFuture.wait_for(0s) == std::future_status::ready; + if (cShutdownCalled || !initialized || pCmd == nullptr) { return; } diff --git a/src/ui/qml/AuthModel.cpp b/src/ui/qml/AuthModel.cpp index 67e590a8a..90719f1b6 100644 --- a/src/ui/qml/AuthModel.cpp +++ b/src/ui/qml/AuthModel.cpp @@ -212,7 +212,7 @@ void AuthModel::onDidAuthenticateEac1Changed() if (mContext) { const QSharedPointer& didAuthenticateEAC1 = mContext->getDidAuthenticateEac1(); - const QString newTransactionInfo = didAuthenticateEAC1.isNull() ? QString() : didAuthenticateEAC1->getTransactionInfo(); + const QString newTransactionInfo = didAuthenticateEAC1.isNull() ? QString() : didAuthenticateEAC1->getTransactionInfo().toHtmlEscaped(); if (newTransactionInfo != mTransactionInfo) { mTransactionInfo = newTransactionInfo; diff --git a/src/ui/qml/modules/AuthView/+desktop/EditRights.qml b/src/ui/qml/modules/AuthView/+desktop/EditRights.qml index 85ccd132f..7fa930aa2 100644 --- a/src/ui/qml/modules/AuthView/+desktop/EditRights.qml +++ b/src/ui/qml/modules/AuthView/+desktop/EditRights.qml @@ -107,6 +107,7 @@ SectionPage { Accessible.name: transactionText.text activeFocusOnTab: true text: AuthModel.transactionInfo + textFormat: Text.PlainText visible: !!text FocusFrame { diff --git a/src/ui/qml/modules/AuthView/+mobile/EditRights.qml b/src/ui/qml/modules/AuthView/+mobile/EditRights.qml index 0ff4b458e..de3a7adf0 100644 --- a/src/ui/qml/modules/AuthView/+mobile/EditRights.qml +++ b/src/ui/qml/modules/AuthView/+mobile/EditRights.qml @@ -87,6 +87,7 @@ FlickableSectionPage { GText { activeFocusOnTab: true text: workflowModel.transactionInfo + textFormat: Text.PlainText visible: !!text width: parent.width } diff --git a/src/ui/qml/modules/ChangePinView/+desktop/ChangePinView.qml b/src/ui/qml/modules/ChangePinView/+desktop/ChangePinView.qml index d6cde7aab..f09219259 100644 --- a/src/ui/qml/modules/ChangePinView/+desktop/ChangePinView.qml +++ b/src/ui/qml/modules/ChangePinView/+desktop/ChangePinView.qml @@ -80,8 +80,13 @@ SectionPage { } } - Keys.onEscapePressed: if (d.cancelAllowed) - ChangePinModel.cancelWorkflow() + Keys.onEscapePressed: event => { + if (d.cancelAllowed) { + ChangePinModel.cancelWorkflow(); + } else { + event.accepted = false; + } + } QtObject { id: d diff --git a/src/ui/qml/modules/ChangePinView/+mobile/ChangePinView.qml b/src/ui/qml/modules/ChangePinView/+mobile/ChangePinView.qml index fe1e2efe4..5ab0b793a 100644 --- a/src/ui/qml/modules/ChangePinView/+mobile/ChangePinView.qml +++ b/src/ui/qml/modules/ChangePinView/+mobile/ChangePinView.qml @@ -28,11 +28,8 @@ SectionPage { contentIsScrolled: !changePinViewContent.atYBeginning smartEidUsed: isSmartWorkflow - title: NumberModel.passwordType === NumberModel.PasswordType.TRANSPORT_PIN ? //: LABEL ANDROID IOS - qsTr("Change Transport PIN") : - //: LABEL ANDROID IOS - qsTr("Change PIN") + title: qsTr("Change PIN") navigationAction: NavigationAction { action: NavigationAction.Action.Back diff --git a/src/ui/qml/modules/ChangePinView/+mobile/internal/ChangePinController.qml b/src/ui/qml/modules/ChangePinView/+mobile/internal/ChangePinController.qml index 42dbdc9de..750362b9f 100644 --- a/src/ui/qml/modules/ChangePinView/+mobile/internal/ChangePinController.qml +++ b/src/ui/qml/modules/ChangePinView/+mobile/internal/ChangePinController.qml @@ -304,6 +304,7 @@ Controller { } onPasswordEntered: pPasswordType => { + pop(); switch (pPasswordType) { case NumberModel.PasswordType.NEW_PIN: case NumberModel.PasswordType.NEW_SMART_PIN: @@ -312,7 +313,6 @@ Controller { case NumberModel.PasswordType.NEW_PIN_CONFIRMATION: case NumberModel.PasswordType.NEW_SMART_PIN_CONFIRMATION: if (NumberModel.commitNewPin()) { - pop(); rootController.isNewPin = true; ChangePinModel.continueWorkflow(); } else { @@ -320,7 +320,6 @@ Controller { } break; default: - pop(); ChangePinModel.continueWorkflow(); } } diff --git a/src/ui/qml/modules/ChangePinView/internal/ChangePinViewContent.qml b/src/ui/qml/modules/ChangePinView/internal/ChangePinViewContent.qml index 1daa87bd8..d496080db 100644 --- a/src/ui/qml/modules/ChangePinView/internal/ChangePinViewContent.qml +++ b/src/ui/qml/modules/ChangePinView/internal/ChangePinViewContent.qml @@ -7,6 +7,7 @@ import Governikus.Global import Governikus.PasswordInfoView import Governikus.Style import Governikus.Type +import Governikus.View GFlickableColumnLayout { id: root @@ -27,11 +28,15 @@ GFlickableColumnLayout { Layout.alignment: Qt.AlignHCenter Layout.topMargin: Constants.component_spacing + activeFocusOnTab: true //: LABEL ALL_PLATFORMS text: qsTr("What kind of PIN do you have?") textStyle: Style.text.headline wrapMode: Text.WordWrap + + FocusFrame { + } } MoreInformationLink { Layout.alignment: Qt.AlignHCenter diff --git a/src/ui/qml/modules/Global/+desktop/TabbedPane.qml b/src/ui/qml/modules/Global/+desktop/TabbedPane.qml index cb0678dd8..e76de4028 100644 --- a/src/ui/qml/modules/Global/+desktop/TabbedPane.qml +++ b/src/ui/qml/modules/Global/+desktop/TabbedPane.qml @@ -134,20 +134,21 @@ Item { Item { id: delegateItem - //: LABEL DESKTOP Additional description of TabbedPane behavior for a11y. - readonly property string a11yDescription: qsTr("You may navigate to different tabs by using the up/down arrows.") + //: LABEL DESKTOP %1 is the current selected Page of %2 Pages + readonly property string a11yPageIndicator: qsTr("%1 of %2").arg(index + 1).arg(ListView.view.count) readonly property bool isFirstItem: index === 0 readonly property bool isLastItem: index === ListView.view.count - 1 readonly property var itemModel: model readonly property bool nextItemIsHighlighted: index === ListView.view.currentIndex - 1 || index === root.highlightedIndex - 1 - Accessible.description: a11yDescription + Accessible.description: Qt.platform.os === "windows" ? a11yPageIndicator : "" Accessible.focusable: true Accessible.name: { if (Qt.platform.os === "windows") { - return sectionName.text + ", " + a11yDescription; + return sectionName.text; } - return sectionName.text + ", " + qsTr("Tab selected"); + //: LABEL DESKTOP + return sectionName.text + ", " + qsTr("Tab selected") + ", " + a11yPageIndicator; } Accessible.role: Accessible.PageTab activeFocusOnTab: false diff --git a/src/ui/qml/modules/Global/GCrossBlendedText.qml b/src/ui/qml/modules/Global/GCrossBlendedText.qml index 37dd17615..09cf922c7 100644 --- a/src/ui/qml/modules/Global/GCrossBlendedText.qml +++ b/src/ui/qml/modules/Global/GCrossBlendedText.qml @@ -28,6 +28,14 @@ Item { implicitHeight: Math.max(mainText.implicitHeight, tempText.implicitHeight) implicitWidth: Math.max(mainText.implicitWidth, tempText.implicitWidth) + Behavior on implicitHeight { + enabled: SettingsModel.useAnimations && !Constants.is_desktop + + NumberAnimation { + duration: mainText.text === "" ? 0 : Constants.animation_duration + } + } + GText { id: mainText @@ -71,6 +79,11 @@ Item { target: mainText to: 1 } + PropertyAction { + property: "text" + target: tempText + value: "" + } } } } diff --git a/src/ui/qml/modules/Global/GFlickable.qml b/src/ui/qml/modules/Global/GFlickable.qml index f11d647d5..3ccc05a54 100644 --- a/src/ui/qml/modules/Global/GFlickable.qml +++ b/src/ui/qml/modules/Global/GFlickable.qml @@ -10,9 +10,9 @@ Flickable { id: baseItem function handleKeyPress(key) { - if (key === Qt.Key_PageDown) + if (key === Qt.Key_PageDown || key === Qt.Key_Down) baseItem.scrollPageDown(); - else if (key === Qt.Key_PageUp) + else if (key === Qt.Key_PageUp || key === Qt.Key_Up) baseItem.scrollPageUp(); else if (key === Qt.Key_End) baseItem.contentY = baseItem.contentHeight - baseItem.height; @@ -46,6 +46,7 @@ Flickable { } Accessible.focusable: false + Accessible.ignored: Constants.is_desktop Accessible.role: Accessible.ScrollBar boundsBehavior: Constants.is_desktop ? Flickable.StopAtBounds : (contentHeight <= height ? Flickable.StopAtBounds : Flickable.DragAndOvershootBounds) boundsMovement: Flickable.FollowBoundsBehavior diff --git a/src/ui/qml/modules/Global/internal/BaseConfirmationPopup.qml b/src/ui/qml/modules/Global/internal/BaseConfirmationPopup.qml index c19cf7a5f..435936bd6 100644 --- a/src/ui/qml/modules/Global/internal/BaseConfirmationPopup.qml +++ b/src/ui/qml/modules/Global/internal/BaseConfirmationPopup.qml @@ -23,6 +23,7 @@ Popup { property string cancelButtonText: qsTr("Cancel") default property alias children: customContent.children property int horizontalTextAlignment: Text.AlignLeft + property alias mainTextFormat: mainText.textFormat //: LABEL ALL_PLATFORMS property string okButtonText: qsTr("OK") property int style: ConfirmationPopup.PopupStyle.OkButton | ConfirmationPopup.PopupStyle.CancelButton @@ -91,9 +92,13 @@ Popup { } } GText { + id: mainText + + Layout.maximumWidth: Number.POSITIVE_INFINITY activeFocusOnTab: true horizontalAlignment: root.horizontalTextAlignment text: root.text + textFormat: Text.RichText visible: root.text !== "" FocusFrame { diff --git a/src/ui/qml/modules/Init/+desktop/App.qml b/src/ui/qml/modules/Init/+desktop/App.qml index 195245564..dae1cbe0b 100644 --- a/src/ui/qml/modules/Init/+desktop/App.qml +++ b/src/ui/qml/modules/Init/+desktop/App.qml @@ -118,8 +118,44 @@ ApplicationWindow { } function closeOpenDialogs() { closeWarning.close(); + quitWarning.close(); abortWorkflowWarning.close(); } + function ensureHeight(pMargin) { + let preferredScreenHeight = appWindow.screen.height - 2 * pMargin; + if (appWindow.height > preferredScreenHeight) { + appWindow.height = preferredScreenHeight; + } + } + function ensureScreenFit() { + let windowMargin = 50; + let screenMinX = appWindow.screen.virtualX; + if (appWindow.x < screenMinX) { + ensureWidth(windowMargin); + appWindow.x = screenMinX + windowMargin; + } + let screenMinY = appWindow.screen.virtualY; + if (appWindow.y < screenMinY) { + ensureHeight(windowMargin); + appWindow.y = screenMinY + windowMargin; + } + let screenMaxX = screenMinX + appWindow.screen.width; + if (appWindow.x + appWindow.width > screenMaxX) { + ensureWidth(windowMargin); + appWindow.x = screenMaxX - appWindow.width - windowMargin; + } + let screenMaxY = screenMinY + appWindow.screen.height; + if (appWindow.y + appWindow.height > screenMaxY) { + ensureHeight(windowMargin); + appWindow.y = screenMaxY - appWindow.height - windowMargin; + } + } + function ensureWidth(pMargin) { + let preferredScreenWidth = appWindow.screen.width - 2 * pMargin; + if (appWindow.width > preferredScreenWidth) { + appWindow.width = preferredScreenWidth; + } + } function hideUiAndTaskbarEntry() { hide(); UiPluginModel.hideFromTaskbar(); @@ -158,6 +194,7 @@ ApplicationWindow { ConfirmationPopup { closePolicy: Popup.NoAutoClose + mainTextFormat: Text.PlainText style: ConfirmationPopup.PopupStyle.NoButtons //: INFO DESKTOP The AA2 is currently remote controlled via the SDK interface, concurrent usage of the AA2 is not possible. title: qsTr("Another application uses %1").arg(Qt.application.name) @@ -282,6 +319,7 @@ ApplicationWindow { } break; } + d.ensureScreenFit(); } target: UiPluginModel diff --git a/src/ui/qml/modules/MainView/+mobile/MainView.qml b/src/ui/qml/modules/MainView/+mobile/MainView.qml index fef36d56d..f639e21bb 100644 --- a/src/ui/qml/modules/MainView/+mobile/MainView.qml +++ b/src/ui/qml/modules/MainView/+mobile/MainView.qml @@ -28,6 +28,7 @@ FlickableSectionPage { Accessible.ignored: tileView.allItemsVisible ? false : index !== tileView.currentIndex Accessible.name: titleText + ". " + qsTr("Item %1 of %2").arg(index + 1).arg(tileView.count) + (tileView.allItemsVisible ? "" : " . " + tileView.scrollHint) activeFocusOnTab: false + focusPolicy: Qt.TabFocus height: ListView.view.height image: imagePath title: titleText @@ -38,11 +39,13 @@ FlickableSectionPage { Accessible.onScrollRightAction: if (tileView.isIos) tileView.scrollPageRight() Component.onCompleted: tileDelegate.DelegateModel.inItems = module !== UiModule.SMART_EID || ApplicationModel.isSmartSupported - onClicked: show(module) + onClicked: root.show(module) + PointHandler { + onGrabChanged: tileView.focus = false + } FocusFrame { marginFactor: -2 - visible: UiPluginModel.isChromeOS } } model: ListModel { diff --git a/src/ui/qml/modules/PasswordInfoView/PasswordInfoData.qml b/src/ui/qml/modules/PasswordInfoView/PasswordInfoData.qml index 6c59c2d03..64cf78123 100644 --- a/src/ui/qml/modules/PasswordInfoView/PasswordInfoData.qml +++ b/src/ui/qml/modules/PasswordInfoView/PasswordInfoData.qml @@ -309,7 +309,7 @@ QtObject { blockTitle: qsTr("Why is the CAN required?") paragraphList: [ //: INFO ALL_PLATFORMS Description text of CAN-allowed authentication - qsTr("The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in red).")] + qsTr("The Card Access Number (CAN) allows to access the imprinted data of the ID card. The CAN is a 6-digit number that can be found on the front of the ID card. It is located at the bottom right next to the validity date (marked in picture).")] } ] }, @@ -328,13 +328,12 @@ QtObject { contentList: [ PasswordInfoContentBlock { - blockHeaderAnimation: AnimationLoader.Type.ENTER_TRANSPORT_PIN paragraphList: [ //: INFO ALL_PLATFORMS Description text explaining the PINs 1/7 qsTr("Your ID card comes with a 5-digit %1Transport PIN%2 which you need to %1replace with%2 a 6-digit %1card PIN%2 that you choose yourself.").arg("").arg("")] }, PasswordInfoContentBlock { - blockHeaderAnimation: AnimationLoader.Type.ENTER_PIN + blockHeaderAnimation: AnimationLoader.Type.ENTER_TRANSPORT_PIN //: LABEL ALL_PLATFORMS blockTitle: qsTr("5-digit Transport PIN") paragraphList: [ @@ -344,6 +343,7 @@ QtObject { qsTr("When you set up the eID function, you will %1replace%2 this 5-digit %1Transport PIN%2 with a 6-digit %1card PIN that you choose yourself%2.").arg("").arg("")] }, PasswordInfoContentBlock { + blockHeaderAnimation: AnimationLoader.Type.ENTER_PIN //: LABEL ALL_PLATFORMS blockTitle: qsTr("6-digit PIN") paragraphList: ApplicationModel.isSmartSupported ? [ diff --git a/src/ui/qml/modules/RemoteServiceView/+mobile/RemoteServiceView.qml b/src/ui/qml/modules/RemoteServiceView/+mobile/RemoteServiceView.qml index be8bafbb0..06c80a9ad 100644 --- a/src/ui/qml/modules/RemoteServiceView/+mobile/RemoteServiceView.qml +++ b/src/ui/qml/modules/RemoteServiceView/+mobile/RemoteServiceView.qml @@ -88,7 +88,7 @@ FlickableSectionPage { readonly property string currentPin: RemoteServiceModel.psk //: INFO ANDROID IOS - readonly property string enterCodeString: qsTr("Enter the pairing code %1 in the %2 on your other device.") + readonly property string enterCodeString: qsTr("Enter the pairing code \"%1\" in the %2 on your other device.") Accessible.name: text Layout.alignment: Qt.AlignHCenter @@ -149,7 +149,7 @@ FlickableSectionPage { GText { id: pairingCode - readonly property string currentPin: RemoteServiceModel.psk.toString() + readonly property string currentPin: RemoteServiceModel.psk Accessible.ignored: true Layout.alignment: Qt.AlignHCenter @@ -205,6 +205,7 @@ FlickableSectionPage { model: RemoteServiceModel.allDevices delegate: DevicesListDelegate { + Layout.fillWidth: true highlightTitle: isLastAddedDevice linkQualityVisible: false title: remoteDeviceName diff --git a/src/ui/qml/modules/RemoteServiceView/+mobile/internal/DevicesListDelegate.qml b/src/ui/qml/modules/RemoteServiceView/+mobile/internal/DevicesListDelegate.qml index 7f2829fda..bb032abca 100644 --- a/src/ui/qml/modules/RemoteServiceView/+mobile/internal/DevicesListDelegate.qml +++ b/src/ui/qml/modules/RemoteServiceView/+mobile/internal/DevicesListDelegate.qml @@ -46,6 +46,7 @@ MouseArea { Accessible.ignored: true elide: Text.ElideRight maximumLineCount: 1 + textFormat: Text.PlainText textStyle: Style.text.subline } GText { diff --git a/src/ui/qml/modules/RemoteServiceView/+mobile/internal/PairingCodeInfoView.qml b/src/ui/qml/modules/RemoteServiceView/+mobile/internal/PairingCodeInfoView.qml index 53901ed74..cbf5f0955 100644 --- a/src/ui/qml/modules/RemoteServiceView/+mobile/internal/PairingCodeInfoView.qml +++ b/src/ui/qml/modules/RemoteServiceView/+mobile/internal/PairingCodeInfoView.qml @@ -11,6 +11,7 @@ import Governikus.View import Governikus.Type FlickableSectionPage { + readonly property string currentPin: RemoteServiceModel.psk property alias text: descriptionContainer.title signal navActionClicked @@ -47,12 +48,14 @@ FlickableSectionPage { } Repeater { model: [ - //: LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 3 + //: LABEL ANDROID IOS Assistance text for pairing new devices. Step 1 of 4 qsTr("Open %1 on your %2other device%3.").arg(Qt.application.name).arg("").arg(""), - //: LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 3. %1 and %2 are surrounding tags for bold font. + //: LABEL ANDROID IOS Assistance text for pairing new devices. Step 2 of 4. %1 and %2 are surrounding tags for bold font. qsTr("On that device go to %1Settings%2 and then %1Smartphone as card reader%2 resp. %1Manage pairings%2.").arg("").arg(""), - //: LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 3 - qsTr("Choose this smartphone in the list to pair it.")] + //: LABEL ANDROID IOS Assistance text for pairing new devices. Step 3 of 4 + qsTr("Choose this smartphone in the list to pair it."), + //: LABEL ANDROID IOS Provide pairing code. Step 4 of 4 + qsTr("Enter the pairing code \"%1\".").arg(currentPin)] GText { Accessible.name: ApplicationModel.stripHtmlTags(text) diff --git a/src/ui/qml/modules/RemoteServiceView/+mobile/internal/RemoteServiceViewRemote.qml b/src/ui/qml/modules/RemoteServiceView/+mobile/internal/RemoteServiceViewRemote.qml index 3e9e64597..985e42b24 100644 --- a/src/ui/qml/modules/RemoteServiceView/+mobile/internal/RemoteServiceViewRemote.qml +++ b/src/ui/qml/modules/RemoteServiceView/+mobile/internal/RemoteServiceViewRemote.qml @@ -131,7 +131,7 @@ Item { GListView { id: searchDeviceList - height: childrenRect.height + height: contentHeight model: RemoteServiceModel.availableDevicesInPairingMode spacing: Constants.component_spacing visible: ApplicationModel.wifiEnabled && count > 0 diff --git a/src/ui/qml/modules/SettingsView/+desktop/RemoteReaderView.qml b/src/ui/qml/modules/SettingsView/+desktop/RemoteReaderView.qml index 9d062290e..537d98316 100644 --- a/src/ui/qml/modules/SettingsView/+desktop/RemoteReaderView.qml +++ b/src/ui/qml/modules/SettingsView/+desktop/RemoteReaderView.qml @@ -73,16 +73,13 @@ Item { title: qsTr("Add pairing") width: parent.width - GListView { + Repeater { id: availableDevices - Layout.fillWidth: true - implicitHeight: contentHeight model: RemoteServiceModel.availableDevicesInPairingMode delegate: RemoteReaderDelegate { - height: implicitHeight + Constants.pane_padding - width: availableDevices.width + Layout.fillWidth: true onPairDevice: pDeviceId => root.pairDevice(pDeviceId) } diff --git a/src/ui/qml/modules/SettingsView/+desktop/internal/RemoteReaderDelegate.qml b/src/ui/qml/modules/SettingsView/+desktop/internal/RemoteReaderDelegate.qml index 8cd034274..abb3e0bfa 100644 --- a/src/ui/qml/modules/SettingsView/+desktop/internal/RemoteReaderDelegate.qml +++ b/src/ui/qml/modules/SettingsView/+desktop/internal/RemoteReaderDelegate.qml @@ -8,6 +8,7 @@ import Governikus.Global import Governikus.Style import Governikus.RemoteServiceView import Governikus.View +import Governikus.Type RoundedRectangle { id: root @@ -18,10 +19,13 @@ RoundedRectangle { signal unpairDevice(string pDeviceId) Accessible.name: { - let msg = qsTr("Smartphone named \"%1\"").arg(remoteDeviceName) + subtext.text; - if (isPaired) { + //: INFO DESKTOP Name and status of remote device. %1 is replaced with the name, %2 with the status + let msg = qsTr("Smartphone named \"%1\". %2. ").arg(remoteDeviceName).arg(subtext.text); + if (isPaired && !isPairing) { + //: INFO DESKTOP Text for activation action if the device is paired. return msg + qsTr("Press space to unpair the smartphone \"%1\".").arg(remoteDeviceName); } + //: INFO DESKTOP Text for activation action if the device is unpaired. return msg + qsTr("Press space to pair the smartphone \"%1\".").arg(remoteDeviceName); } Accessible.role: Accessible.Button @@ -30,7 +34,7 @@ RoundedRectangle { implicitHeight: rowLayout.implicitHeight + 2 * rowLayout.anchors.margins implicitWidth: rowLayout.implicitWidth + 2 * rowLayout.anchors.margins - Keys.onSpacePressed: isPaired ? unpairDevice(deviceId) : pairDevice(deviceId) + Keys.onSpacePressed: (isPaired && !isPairing && ApplicationModel.isScreenReaderRunning()) ? unpairDevice(deviceId) : pairDevice(deviceId) FocusFrame { } @@ -48,6 +52,7 @@ RoundedRectangle { elide: Text.ElideRight maximumLineCount: 1 text: remoteDeviceName + textFormat: Text.PlainText textStyle: Style.text.headline width: parent.width } @@ -71,11 +76,14 @@ RoundedRectangle { TintableIcon { id: removeIcon + activeFocusOnTab: !ApplicationModel.isScreenReaderRunning() source: "qrc:///images/trash_icon.svg" sourceSize.height: iconHeight tintColor: Style.color.image visible: isPaired && !isPairing + Keys.onSpacePressed: unpairDevice(deviceId) + MouseArea { id: trashMouse @@ -88,6 +96,8 @@ RoundedRectangle { onClicked: unpairDevice(deviceId) } + FocusFrame { + } } GSpacer { height: removeIcon.height diff --git a/src/ui/qml/modules/Style/internal/ColorsDark.qml b/src/ui/qml/modules/Style/internal/ColorsDark.qml index 672f82690..93ce25041 100644 --- a/src/ui/qml/modules/Style/internal/ColorsDark.qml +++ b/src/ui/qml/modules/Style/internal/ColorsDark.qml @@ -26,6 +26,7 @@ Colors { background.pressed: "#80cdec" border.pressed: "#80cdec" content.basic: "#ffffff" + content.checked: "#0098eb" content.pressed: "#ffffff" } controlRadiobutton: DefaultControlColors { diff --git a/src/ui/qml/modules/TitleBar/+desktop/Notifications.qml b/src/ui/qml/modules/TitleBar/+desktop/Notifications.qml index 8e505eb22..3b5096bdf 100644 --- a/src/ui/qml/modules/TitleBar/+desktop/Notifications.qml +++ b/src/ui/qml/modules/TitleBar/+desktop/Notifications.qml @@ -76,8 +76,8 @@ Item { GListView { id: logEntryList + activeFocusOnTab: d.fadeIn && !fadeOutTimer.running anchors.fill: parent - anchors.leftMargin: Constants.pane_padding bottomMargin: Constants.pane_padding clip: true model: NotificationModel @@ -89,13 +89,15 @@ Item { delegate: Item { Accessible.name: notificationTime.text + " " + notificationBody.text - activeFocusOnTab: d.fadeIn && !fadeOutTimer.running - height: row.height - width: row.width + Accessible.role: Accessible.StaticText + implicitHeight: row.height + implicitWidth: row.width + 2 * Constants.pane_padding Row { id: row + anchors.left: parent.left + anchors.leftMargin: Constants.pane_padding spacing: logEntryList.spacing Component.onCompleted: { @@ -123,10 +125,12 @@ Item { color: model.type === "developermode" ? Style.color.warning : Style.color.control.content.basic text: model.text - width: logEntryList.width - notificationTime.width - 3 * logEntryList.spacing + width: logEntryList.width - 2 * Constants.pane_padding - notificationTime.width - 3 * logEntryList.spacing } } FocusFrame { + borderColor: Style.color.control.content.basic + framee: row } } diff --git a/src/ui/qml/modules/TitleBar/+desktop/TitleBar.qml b/src/ui/qml/modules/TitleBar/+desktop/TitleBar.qml index 2a41f6cec..bdc2b3475 100644 --- a/src/ui/qml/modules/TitleBar/+desktop/TitleBar.qml +++ b/src/ui/qml/modules/TitleBar/+desktop/TitleBar.qml @@ -62,6 +62,7 @@ Rectangle { height: rootAction.height + 2 * Style.dimens.titlebar_padding width: parent.width + z: 1 TitleBarAction { id: rootAction @@ -109,6 +110,15 @@ Rectangle { onClicked: notifications.toggle() } } + Notifications { + id: notifications + + anchors.left: parent.right + anchors.top: parent.top + anchors.topMargin: firstRow.height + + onNewNotification: notifyButton.notify() + } } TitlePane { id: titlePane @@ -165,13 +175,4 @@ Rectangle { right: parent.right } } - Notifications { - id: notifications - - anchors.left: parent.right - anchors.top: parent.top - anchors.topMargin: firstRow.height - - onNewNotification: notifyButton.notify() - } } diff --git a/src/ui/qml/modules/UpdateView/+desktop/UpdateView.qml b/src/ui/qml/modules/UpdateView/+desktop/UpdateView.qml index 7bf085cb8..a3bd0fee3 100644 --- a/src/ui/qml/modules/UpdateView/+desktop/UpdateView.qml +++ b/src/ui/qml/modules/UpdateView/+desktop/UpdateView.qml @@ -26,6 +26,18 @@ FlickableSectionPage { titleBarAction: TitleBarAction { //: LABEL DESKTOP text: qsTr("Application update") + + customSubAction: NavigationAction { + type: root.downloadRunning ? NavigationAction.Action.Cancel : NavigationAction.Action.Back + visible: true + + onClicked: { + if (root.downloadRunning) { + root.update.abortDownload(); + } + root.leaveView(); + } + } } ResultView { diff --git a/src/ui/webservice/UiPluginWebService.cpp b/src/ui/webservice/UiPluginWebService.cpp index b2a42f2b3..22c4256b4 100644 --- a/src/ui/webservice/UiPluginWebService.cpp +++ b/src/ui/webservice/UiPluginWebService.cpp @@ -55,7 +55,7 @@ bool UiPluginWebService::listening() for (const auto& address : std::as_const(HttpServer::cAddresses)) { HttpServerStatusParser parser(port, address); - const QString serverAppName = parser.request() ? parser.getVersionInfo().getImplementationTitle() : parser.getServerHeader(); + const QString serverAppName = (parser.request() ? parser.getVersionInfo().getImplementationTitle() : parser.getServerHeader()).toHtmlEscaped(); if (serverAppName.startsWith(VersionInfo::getInstance().getImplementationTitle())) { switch (handleExistingApp(port, address)) @@ -150,7 +150,7 @@ void UiPluginWebService::handleShowUiRequest(const QString& pUiModule, const QSh { pRequest->send(HTTP_STATUS_OK); - QString userAgent = QString::fromLatin1(pRequest->getHeader(QByteArrayLiteral("user-agent"))); + QString userAgent = QString::fromLatin1(pRequest->getHeader(QByteArrayLiteral("user-agent"))).toHtmlEscaped(); if (userAgent.startsWith(VersionInfo::getInstance().getImplementationTitle())) { QString version = userAgent.remove(VersionInfo::getInstance().getImplementationTitle() + QLatin1Char('/')).split(QLatin1Char(' ')).at(0); diff --git a/src/ui/websocket/UiPluginWebSocket.cpp b/src/ui/websocket/UiPluginWebSocket.cpp index a8bbf26c6..3e4fb7cda 100644 --- a/src/ui/websocket/UiPluginWebSocket.cpp +++ b/src/ui/websocket/UiPluginWebSocket.cpp @@ -150,7 +150,7 @@ void UiPluginWebSocket::onNewWebSocketRequest(const QSharedPointer& } mRequest = pRequest; - Q_EMIT fireUiDominationRequest(this, QString::fromLatin1(pRequest->getHeader().value(QByteArrayLiteral("user-agent")))); + Q_EMIT fireUiDominationRequest(this, QString::fromLatin1(pRequest->getHeader().value(QByteArrayLiteral("user-agent"))).toHtmlEscaped()); } diff --git a/src/workflows/base/states/StateConnectCard.cpp b/src/workflows/base/states/StateConnectCard.cpp index 028c30050..2c7feae6e 100644 --- a/src/workflows/base/states/StateConnectCard.cpp +++ b/src/workflows/base/states/StateConnectCard.cpp @@ -64,17 +64,12 @@ void StateConnectCard::onCommandDone(QSharedPointer context->setCardConnection(cardConnection); const auto& readerInfo = cardConnection->getReaderInfo(); - if (readerInfo.insufficientApduLength()) - { - //: INFO IOS - context->getCardConnection()->setProgressMessage(tr("The used card reader does not meet the technical requirements (Extended Length not supported).")); - return; - } + Q_ASSERT(!readerInfo.insufficientApduLength()); if (context->eidTypeMismatch()) { //: INFO IOS - context->getCardConnection()->setProgressMessage(tr("The used ID card type is not accepted by the server.")); + context->getCardConnection()->setErrorMessage(tr("The used ID card type is not accepted by the server.")); return; } @@ -84,7 +79,7 @@ void StateConnectCard::onCommandDone(QSharedPointer const GlobalStatus status = GlobalStatus::Code::Card_Pin_Deactivated; if (Env::getSingleton()->isUsedAsSDK()) { - context->getCardConnection()->setProgressMessage(status.toErrorDescription()); + context->getCardConnection()->setErrorMessage(status.toErrorDescription()); } else { diff --git a/src/workflows/base/states/StateUnfortunateCardPosition.cpp b/src/workflows/base/states/StateUnfortunateCardPosition.cpp index 0b7b5b75d..d4f3b1c9b 100644 --- a/src/workflows/base/states/StateUnfortunateCardPosition.cpp +++ b/src/workflows/base/states/StateUnfortunateCardPosition.cpp @@ -5,9 +5,11 @@ #include "StateUnfortunateCardPosition.h" #include "AbstractState.h" -#include "Env.h" #include "GenericContextContainer.h" -#include "ReaderManager.h" + +#if defined(Q_OS_IOS) + #include "ReaderManager.h" +#endif using namespace governikus; diff --git a/test/fixture/fixture.qrc b/test/fixture/fixture.qrc index 2ab04a871..c773d86d1 100644 --- a/test/fixture/fixture.qrc +++ b/test/fixture/fixture.qrc @@ -78,6 +78,7 @@ paos/DIDAuthenticateEAC1_accessRightsEmpty.xml paos/DIDAuthenticateEAC1_accessRightsMissing.xml paos/DIDAuthenticateEAC1_TS_TA_2.1.1.xml + paos/DIDAuthenticateEAC1_htmlTransactionInfo.xml paos/DIDAuthenticateEAC2.xml paos/DIDAuthenticateEAC2_template.xml paos/DIDAuthenticateEAC2_template2.xml diff --git a/test/fixture/paos/DIDAuthenticateEAC1_htmlTransactionInfo.xml b/test/fixture/paos/DIDAuthenticateEAC1_htmlTransactionInfo.xml new file mode 100644 index 000000000..31a1d2f41 --- /dev/null +++ b/test/fixture/paos/DIDAuthenticateEAC1_htmlTransactionInfo.xml @@ -0,0 +1,31 @@ + + + + + + + +4549445F4946445F434F4E544558545F42415345 +REINER SCT cyberJack RFID komfort USB 52 +0 +4549445F49534F5F32343732375F42415345 +37343139303333612D616163352D343331352D386464392D656166393664636661653361 + + +PIN + +7f218201487f4e8201005f29010042104445445674494447564e4b30303033357f494f060a04007f0007020202020386410400200547c179a38fc0c9602fae4a3ebaef6702b59d171fdb83b242a098b257253fe8f479095518b1a5fbed45d0c0efce178b1ca6cb059ea56d7f9cc0a9ba18b05f200e444544454d4f43414e30303037367f4c12060904007f0007030102025305000513ff175f25060200000502015f2406020000060200655e732d060904007f00070301030180206349cf9eebd2da97dfde6d5f94c467b6dec4c65336e61f2a19114f71eff57077732d060904007f0007030103028020bc09df81284968da37eacb8539977f63181e03b4b2788192befffc54c4c2cba25f3740a792b69f2811d066aa1deeaaf2cb321ac950f33512ee7cd9615bc945cfdca48c3bcbea73a388539aa31b59ac7cddb8e9678c7b1acea263cf6435fbdf3b436ed0 +7f218201b67f4e82016e5f290100420e44455445535465494430303030317f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7864104096eb58bfd86252238ec2652185c43c3a56c320681a21e37a8e69ddc387c0c5f5513856efe2fdc656e604893212e29449b365e304605ac5413e75be31e641f128701015f200e44455445535465494430303030327f4c12060904007f0007030102025305fe0f01ffff5f25060100000902015f24060103000902015f3740141120a0fdfc011a52f3f72b387a3dc7aca88b4868d5ae9741780b6ff8a0b49e5f55169a2d298ef5cf95935dca0c3df3e9d42dc45f74f2066317154961e6c746 +7f218201b67f4e82016e5f290100420e44455445535465494430303030327f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a786410474ff63ab838c73c303ac003dfee95cf8bf55f91e8febcb7395d942036e47cf1845ec786ec95bb453aac288ad023b6067913cf9b63f908f49304e5cfc8b3050dd8701015f200e44455445535465494430303030347f4c12060904007f0007030102025305fc0f13ffff5f25060102000501015f24060105000501015f37405c035a0611b6c58f0b5261fdd009decab7dc7a79482d5248cca119059b7d82b2157cf0c4a499bcf441efdd35e294a58c0af19a34a0762159533285acf170a505 +7f218201b67f4e82016e5f290100420e44455445535465494430303030347f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a78641049bfeba8dc7faab6e3bdeb3ff794dbb800848fe4f6940a4cc7eecb5159c87da5395505892026d420a22596cd014ed1fd872dada597db0f8d64441041198f62d448701015f200e44455445535465494430303030357f4c12060904007f0007030102025305fc0f13ffff5f25060105000500045f24060108000500045f37402d2468416d66bcbe259b9b907a73395bc1ef94ed75f9c17615210246e9efb06e6753e9055ce76623b7699b9efb1a7d3a9dd83f6e6e09e55a33ea0a5f62a1c719 +7f218201b67f4e82016e5f290100420e44455445535465494430303030357f4982011d060a04007f000702020202038120a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e537782207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9832026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b68441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f0469978520a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a786410425ab80f9c7bca0ab1759d8e469f911cc006d02131552aa5f248b2a38d7c72cfb3317ea6881fd24d8b31a2e75fbeda87964b60787095f75c753cd8bc5264d3c9a8701015f200e44455445535465494430303030367f4c12060904007f0007030102025305fc0f13ffff5f25060108000200055f24060201000200055f37402e55923ed687cb104d609dd183402e8292db03c3effe5ef3fac597d2a8db27370269eaad7341d72447c9184cd817ae0e2bd4df6fcf89dc52f455d490f077e5e9 +7f2181e77f4e81a05f290100420e44455445535465494430303030367f494f060a04007f00070202020203864104451a9e4d7bc410319112cb43f1aee75e29e74183543e8fa91ccfe5b85c5408c867d45f6f7a3f9c251f52082c7fd1a56bbde2fd93e846a6615b4b0164d0f54cdf5f20104445445674494447564e4b30303033357f4c12060904007f0007030102025305400513ff975f25060200000500085f24060200000800065f374009bee15c4b629dc7a2a34986892d46c4ddaebdc738c49f9956473852d168882f7e4dfc0e3d8ef871bbc59cdcbc37e0347a8c1c95f56edfa3b5f747709a8932b1 +3082013b060a04007f00070301030101a1160c14476f7665726e696b757320546573742044564341a21a1318687474703a2f2f7777772e676f7665726e696b75732e6465a31a0c18476f7665726e696b757320476d6248202620436f2e204b47a420131e68747470733a2f2f746573742e676f7665726e696b75732d6569642e6465a581940c81914e616d652c20416e7363687269667420756e6420452d4d61696c2d4164726573736520646573204469656e737465616e626965746572733a0d0a476f7665726e696b757320476d6248202620436f2e204b470d0a486f6368736368756c72696e6720340d0a3238333539204272656d656e0d0a452d4d61696c3a206b6f6e74616b7440676f7665726e696b75732e646509a72431220420ccb65ac1d48e9cd43876ca82cfe83c43d711294d4a40f68811acb715aaa6c8ab +7F4C12060904007F00070301020253050001137C05 +7F4C12060904007F00070301020253050004008302 +67447315060904007F000703010401530831393932313230367315060904007F000703010402530832303133313230367314060904007F000703010403530702760400110000 +this is a <a>test</a> for TransactionInfo + + + + diff --git a/test/qt/card/base/test_Card.cpp b/test/qt/card/base/test_Card.cpp new file mode 100644 index 000000000..183869a31 --- /dev/null +++ b/test/qt/card/base/test_Card.cpp @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2024 Governikus GmbH & Co. KG, Germany + */ + +#include "VolatileSettings.h" + +#include "Card.h" + +#include + + +using namespace governikus; + + +class test_Card + : public QObject +{ + Q_OBJECT + + private Q_SLOTS: + void initTestCase() + { + Env::getSingleton()->setMessages(VolatileSettings::Messages( + QStringLiteral("scan started"), + QStringLiteral("scan failed"), + QStringLiteral("scan succeded"), + QStringLiteral("scan progress"))); + } + + + void test_generateProgressMessage_data() + { + QTest::addColumn("sdk"); + QTest::addColumn("message"); + QTest::addColumn("progress"); + QTest::addColumn("expectedMessage"); + + QTest::addRow("Message without Progress") << false << "specific message" << -1 << "specific message"; + QTest::addRow("Message with Progress") << false << "specific message" << 20 << "specific message\n20 %"; + QTest::addRow("No Message but Progress") << false << QString() << 30 << "30 %"; + + QTest::addRow("SDK - Message without Progress") << true << "specific message" << -1 << "scan progress\n0 %"; + QTest::addRow("SDK - Message with Progress") << true << "specific message" << 20 << "scan progress\n20 %"; + QTest::addRow("SDK - No Message but Progress") << true << QString() << 30 << "scan progress\n30 %"; + } + + + void test_generateProgressMessage() + { + QFETCH(bool, sdk); + QFETCH(QString, message); + QFETCH(int, progress); + QFETCH(QString, expectedMessage); + + Env::getSingleton()->setUsedAsSDK(sdk); + const auto result = Card::generateProgressMessage(message, progress); + QCOMPARE(result, expectedMessage); + } + + + void test_generateErrorMessage_data() + { + QTest::addColumn("sdk"); + QTest::addColumn("message"); + QTest::addColumn("expectedMessage"); + + QTest::addRow("Normal message") << false << "specific message" << "specific message"; + QTest::addRow("Null message") << false << QString() << QString(); + QTest::addRow("Empty message") << false << QStringLiteral("") << QStringLiteral(""); + + QTest::addRow("SDK - Normal message") << true << "specific message" << "scan failed"; + QTest::addRow("SDK - Null message") << true << QString() << QString(); + QTest::addRow("SDK - Empty message") << true << QStringLiteral("") << "scan failed"; + } + + + void test_generateErrorMessage() + { + QFETCH(bool, sdk); + QFETCH(QString, message); + QFETCH(QString, expectedMessage); + + Env::getSingleton()->setUsedAsSDK(sdk); + const auto result = Card::generateErrorMessage(message); + QCOMPARE(result, expectedMessage); + } + + +}; + +QTEST_GUILESS_MAIN(test_Card) +#include "test_Card.moc" diff --git a/test/qt/ifd/messages/test_Discovery.cpp b/test/qt/ifd/messages/test_Discovery.cpp index 54a781a55..e0453d7d7 100644 --- a/test/qt/ifd/messages/test_Discovery.cpp +++ b/test/qt/ifd/messages/test_Discovery.cpp @@ -168,7 +168,7 @@ class test_Discovery QCOMPARE(discovery.getType(), IfdMessageType::UNDEFINED); QCOMPARE(discovery.getContextHandle(), QString()); QCOMPARE(discovery.getIfdName(), QStringLiteral("Sony Xperia Z5 compact")); - QCOMPARE(discovery.getIfdId(), QStringLiteral("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")); + QCOMPARE(discovery.getIfdId(), QStringLiteral("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF").toLower()); QVERIFY(discovery.getPort() == static_cast(24728)); QCOMPARE(discovery.getSupportedApis(), QList({IfdVersion::Version::v0})); QCOMPARE(discovery.getPairing(), pairing); @@ -439,7 +439,7 @@ class test_Discovery const Discovery discovery(obj); QCOMPARE(discovery.isIncomplete(), incomplete); - QCOMPARE(discovery.getIfdId(), QString::fromLatin1(ifdid)); + QCOMPARE(discovery.getIfdId(), QString::fromLatin1(ifdid).toLower()); QCOMPARE(logSpy.count(), incomplete ? 1 : 0); if (incomplete) @@ -449,18 +449,30 @@ class test_Discovery } + void sameIfdId_data() + { + QTest::addColumn("json_ifdid"); + + QTest::newRow("lower case") << QByteArray("0575e99867361c26442ece18bed6f955ab7dd269ae8f42d3a21af0e734c3d8d9"); + QTest::newRow("upper case") << QByteArray("0575E99867361C26442ECE18BED6F955AB7DD269AE8F42D3A21AF0E734C3D8D9"); + } + + void sameIfdId() { + QFETCH(QByteArray, json_ifdid); + QSignalSpy logSpy(Env::getSingleton()->getEventHandler(), &LogEventHandler::fireLog); - const QByteArray messageHash(R"({ - "IFDID": "0575e99867361c26442ece18bed6f955ab7dd269ae8f42d3a21af0e734c3d8d9", + QByteArray messageHash(R"({ + "IFDID": "[IFDID]", "IFDName": "Sony Xperia Z5 compact", "SupportedAPI": ["IFDInterface_WebSocket_v0"], "msg": "REMOTE_IFD", "pairing": true, "port": 24728 })"); + messageHash.replace("[IFDID]", json_ifdid); const QJsonObject& objHash = QJsonDocument::fromJson(messageHash).object(); const Discovery discoveryHash(objHash); QCOMPARE(logSpy.count(), 0); diff --git a/test/qt/ifd/remote/test_RemoteReaderAdvertiser.cpp b/test/qt/ifd/remote/test_RemoteReaderAdvertiser.cpp index eae9533c1..116ad1174 100644 --- a/test/qt/ifd/remote/test_RemoteReaderAdvertiser.cpp +++ b/test/qt/ifd/remote/test_RemoteReaderAdvertiser.cpp @@ -106,7 +106,7 @@ class test_RemoteReaderAdvertiser const auto& offerMsg = Discovery(QJsonDocument::fromJson(data).object()); QCOMPARE(offerMsg.getIfdName(), ifdName); - QCOMPARE(offerMsg.getIfdId(), ifdId); + QCOMPARE(offerMsg.getIfdId(), ifdId.toLower()); QCOMPARE(offerMsg.getPort(), port); QCOMPARE(offerMsg.getSupportedApis(), IfdVersion::supported()); QCOMPARE(offerMsg.getPairing(), pairing); diff --git a/test/qt/settings/test_VolatileSettings.cpp b/test/qt/settings/test_VolatileSettings.cpp index 6b6c98f8f..40d4f5944 100644 --- a/test/qt/settings/test_VolatileSettings.cpp +++ b/test/qt/settings/test_VolatileSettings.cpp @@ -70,6 +70,36 @@ class test_VolatileSettings } + void test_Messages_data() + { + QTest::addColumn("started"); + QTest::addColumn("failed"); + QTest::addColumn("succeded"); + QTest::addColumn("progress"); + + QTest::addRow("empty") << QString() << QString() << QString() << QString(); + QTest::addRow("not empty") << QStringLiteral("a") << QStringLiteral("b") << QStringLiteral("c") << QStringLiteral("d"); + } + + + void test_Messages() + { + QFETCH(QString, started); + QFETCH(QString, failed); + QFETCH(QString, succeded); + QFETCH(QString, progress); + + VolatileSettings::Messages messages(started, failed, succeded, progress); + + QVERIFY(!messages.getSessionFailed().isNull()); + + QCOMPARE(messages.getSessionStarted(), started); + QCOMPARE(messages.getSessionFailed(), failed); + QCOMPARE(messages.getSessionSucceeded(), succeded); + QCOMPARE(messages.getSessionInProgress(), progress); + } + + }; QTEST_GUILESS_MAIN(test_VolatileSettings) diff --git a/test/qt/ui/qml/smart/test_SmartModel.cpp b/test/qt/ui/qml/smart/test_SmartModel.cpp index 46cf8e6ce..9f0fe7b49 100644 --- a/test/qt/ui/qml/smart/test_SmartModel.cpp +++ b/test/qt/ui/qml/smart/test_SmartModel.cpp @@ -166,7 +166,7 @@ class test_SmartModel int signalCount = 0; - const auto connection = connect(smartModel, &SmartModel::fireStateChanged, [&signalCount, smartModel](){ + const auto connection = connect(smartModel, &SmartModel::fireStateChanged, this, [&signalCount, smartModel](){ signalCount++; switch (signalCount) diff --git a/test/qt/ui/qml/test_AuthModel.cpp b/test/qt/ui/qml/test_AuthModel.cpp index 4664ffef0..070371f8d 100644 --- a/test/qt/ui/qml/test_AuthModel.cpp +++ b/test/qt/ui/qml/test_AuthModel.cpp @@ -44,14 +44,14 @@ class test_AuthModel QCOMPARE(spyStateEntered.count(), 0); QCOMPARE(spyTransactionInfoChanged.count(), 0); - QByteArray content = TestFileHelper::readFile(":/paos/DIDAuthenticateEAC1.xml"_L1); + QByteArray content = TestFileHelper::readFile(":/paos/DIDAuthenticateEAC1_htmlTransactionInfo.xml"_L1); QSharedPointer eac1(static_cast(DidAuthenticateEac1Parser().parse(content))); context->setDidAuthenticateEac1(eac1); - QCOMPARE(model->getTransactionInfo(), "this is a test for TransactionInfo"_L1); + QCOMPARE(model->getTransactionInfo(), "this is a <a>test</a> for TransactionInfo"_L1); model->resetAuthContext(context); QVERIFY(model->getTransactionInfo().isEmpty()); Q_EMIT context->fireDidAuthenticateEac1Changed(); - QCOMPARE(model->getTransactionInfo(), "this is a test for TransactionInfo"_L1); + QCOMPARE(model->getTransactionInfo(), "this is a <a>test</a> for TransactionInfo"_L1); QCOMPARE(spyWorkflowStarted.count(), 2); QCOMPARE(spyCurrentStateChanged.count(), 2); QCOMPARE(spyStateEntered.count(), 0); diff --git a/test/qt/workflows/states/test_StateConnectCard.cpp b/test/qt/workflows/states/test_StateConnectCard.cpp index cc71f1e0f..59ecabce9 100644 --- a/test/qt/workflows/states/test_StateConnectCard.cpp +++ b/test/qt/workflows/states/test_StateConnectCard.cpp @@ -24,13 +24,15 @@ class test_StateConnectCard { Q_OBJECT QSharedPointer mState; - QSharedPointer mContext; + QSharedPointer mContext; ReaderInfo mReaderInfo; private: - QSharedPointer createCardConnection(QThread& workerThread) + QSharedPointer createCardConnection(QThread& workerThread, const QString& readerName) { - QSharedPointer connectionWorker(new MockCardConnectionWorker()); + MockReader* reader = new MockReader(); + reader->setReaderInfo(ReaderInfo(readerName, ReaderManagerPluginType::NFC, CardInfo(CardType::EID_CARD))); + QSharedPointer connectionWorker(new MockCardConnectionWorker(reader)); connectionWorker->moveToThread(&workerThread); return QSharedPointer(new CardConnection(connectionWorker)); } @@ -77,8 +79,23 @@ class test_StateConnectCard } + void test_OnCommandDone_data() + { + QTest::addColumn("eidTypeMismatch"); + + QTest::addRow("No eID type mismatch") << false; + QTest::addRow("eID type mismatch") << true; + } + + void test_OnCommandDone() { + QFETCH(bool, eidTypeMismatch); + if (eidTypeMismatch) + { + mContext->setAcceptedEidTypes({AcceptedEidType::SE_ENDORSED}); + } + QThread workerThread; workerThread.start(); @@ -95,10 +112,10 @@ class test_StateConnectCard QTest::ignoreMessage(QtDebugMsg, "Card connection command completed"); QTest::ignoreMessage(QtDebugMsg, "Card connection was successful"); - const auto& cardConnection = createCardConnection(workerThread); + const auto& cardConnection = createCardConnection(workerThread, rName); mState->onCommandDone(createCardConnectionCommand(rName, cardConnection)); QCOMPARE(mContext->getCardConnection(), cardConnection); - QCOMPARE(spyContinue.count(), 1); + QCOMPARE(spyContinue.count(), eidTypeMismatch ? 0 : 1); workerThread.quit(); workerThread.wait(); @@ -111,7 +128,7 @@ class test_StateConnectCard workerThread.start(); const auto info = ReaderInfo(QStringLiteral("name")); - const auto cardConnection = createCardConnection(workerThread); + const auto cardConnection = createCardConnection(workerThread, info.getName()); QSignalSpy spy(mState.data(), &StateConnectCard::fireRetry);