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;