From e6aa48dc2ccee84d017f66e304be8619e09d814e Mon Sep 17 00:00:00 2001 From: Juha Vuolle Date: Wed, 14 Aug 2024 12:55:53 +0300 Subject: [PATCH] Introduce qt_internal_add_android_permission CMake function This is a manual cherry-pick from 5efbfcb032d801c7083d4a850d0279a075de7f1a The function allows setting additional permission attributes like minSdkVersion and maxSdkVersion. The function's implementation is such that it should work alongside the older way of directly setting the QT_ANDROID_PERMISSIONS target property. Task-number: QTBUG-129944 Task-number: QTBUG-117358 Task-number: QTBUG-112164 Change-Id: I0f40692574848fccdf65f9baedd14351917ce4bf Reviewed-by: Alexandru Croitor (cherry picked from commit 5efbfcb032d801c7083d4a850d0279a075de7f1a) Reviewed-by: Assam Boudjelthia --- cmake/QtAndroidHelpers.cmake | 50 +++++++++++++++++++++++++++++- src/tools/androiddeployqt/main.cpp | 11 ++++--- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/cmake/QtAndroidHelpers.cmake b/cmake/QtAndroidHelpers.cmake index 0743fe41a96..17af8c9cd88 100644 --- a/cmake/QtAndroidHelpers.cmake +++ b/cmake/QtAndroidHelpers.cmake @@ -88,6 +88,44 @@ macro(qt_internal_setup_android_target_properties) ) endmacro() +function(qt_internal_add_android_permission target) + cmake_parse_arguments(arg "" "NAME" "ATTRIBUTES" ${ARGN}) + + if(NOT target) + message(FATAL_ERROR "Target for adding Android permission cannot be empty (${arg_NAME})") + endif() + + if(NOT arg_NAME) + message(FATAL_ERROR "NAME for adding Android permission cannot be empty (${target})") + endif() + + set(permission_entry "${arg_NAME}") + + if(arg_ATTRIBUTES) + # Permission with additional attributes + list(LENGTH arg_ATTRIBUTES attributes_len) + math(EXPR attributes_modulus "${attributes_len} % 2") + if(NOT (attributes_len GREATER 1 AND attributes_modulus EQUAL 0)) + message(FATAL_ERROR "Android permission attributes must be name-value pairs (${arg_NAME})") + endif() + # Combine name-value pairs + set(index 0) + set(attributes "") + while(index LESS attributes_len) + list(GET arg_ATTRIBUTES ${index} name) + math(EXPR index "${index} + 1") + list(GET arg_ATTRIBUTES ${index} value) + string(APPEND attributes " android:${name}=\"${value}\"") + math(EXPR index "${index} + 1") + endwhile() + set(permission_entry "${permission_entry}\;${attributes}") + endif() + + # Append the permission to the target's property + set_property(TARGET ${target} APPEND PROPERTY QT_ANDROID_PERMISSIONS "${permission_entry}") +endfunction() + + function(qt_internal_android_dependencies_content target file_content_out) get_target_property(arg_JAR_DEPENDENCIES ${target} QT_ANDROID_JAR_DEPENDENCIES) get_target_property(arg_BUNDLED_JAR_DEPENDENCIES ${target} QT_ANDROID_BUNDLED_JAR_DEPENDENCIES) @@ -194,7 +232,17 @@ function(qt_internal_android_dependencies_content target file_content_out) # Android Permissions if(arg_PERMISSIONS) foreach(permission IN LISTS arg_PERMISSIONS) - string(APPEND file_contents "\n") + # Check if the permission has also extra attributes in addition to the permission name + list(LENGTH permission permission_len) + if(permission_len EQUAL 1) + string(APPEND file_contents "\n") + elseif(permission_len EQUAL 2) + list(GET permission 0 name) + list(GET permission 1 extras) + string(APPEND file_contents "\n") + else() + message(FATAL_ERROR "Unexpected permission: " "${permission}" "${permission_len}") + endif() endforeach() endif() diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index f2d3e5bf1de..1f62df05f3d 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -240,7 +240,8 @@ struct Options // Per package collected information QStringList initClasses; - QStringList permissions; + // permissions 'name' => 'optional additional attributes' + QMap permissions; QStringList features; // Override qml import scanner path @@ -1855,8 +1856,8 @@ bool updateAndroidManifest(Options &options) replacements[QStringLiteral("package=\"org.qtproject.example\"")] = "package=\"%1\""_L1.arg(options.packageName); QString permissions; - for (const QString &permission : std::as_const(options.permissions)) - permissions += " \n"_L1.arg(permission); + for (auto [name, extras] : options.permissions.asKeyValueRange()) + permissions += " \n"_L1.arg(name).arg(extras); replacements[QStringLiteral("")] = permissions.trimmed(); QString features; @@ -2127,7 +2128,8 @@ bool readAndroidDependencyXml(Options *options, } } else if (reader.name() == "permission"_L1) { QString name = reader.attributes().value("name"_L1).toString(); - options->permissions.append(name); + QString extras = reader.attributes().value("extras"_L1).toString(); + options->permissions.insert(name, extras); } else if (reader.name() == "feature"_L1) { QString name = reader.attributes().value("name"_L1).toString(); options->features.append(name); @@ -2142,7 +2144,6 @@ bool readAndroidDependencyXml(Options *options, } else if (options->verbose) { fprintf(stdout, "No android dependencies for %s\n", qPrintable(moduleName)); } - options->permissions.removeDuplicates(); options->features.removeDuplicates(); return true;