diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
index 23e3f4139ca2..bc18304c30eb 100644
--- a/doc/classes/EditorExportPlugin.xml
+++ b/doc/classes/EditorExportPlugin.xml
@@ -241,6 +241,14 @@
Return [code]true[/code] if the plugin supports the given [param platform].
+
+
+
+
+
+ Provide access to the Android prebuilt manifest and allows the plugin to modify it if needed.
+
+
diff --git a/editor/export/editor_export_plugin.cpp b/editor/export/editor_export_plugin.cpp
index ddc340ee77fb..dea7c45a7f84 100644
--- a/editor/export/editor_export_plugin.cpp
+++ b/editor/export/editor_export_plugin.cpp
@@ -264,6 +264,12 @@ String EditorExportPlugin::get_android_manifest_element_contents(const Ref &p_export_platform, const PackedByteArray &p_manifest_data) const {
+ PackedByteArray ret;
+ GDVIRTUAL_CALL(_update_android_prebuilt_manifest, p_export_platform, p_manifest_data, ret);
+ return ret;
+}
+
PackedStringArray EditorExportPlugin::_get_export_features(const Ref &p_platform, bool p_debug) const {
PackedStringArray ret;
GDVIRTUAL_CALL(_get_export_features, p_platform, p_debug, ret);
@@ -369,4 +375,5 @@ void EditorExportPlugin::_bind_methods() {
GDVIRTUAL_BIND(_get_android_manifest_activity_element_contents, "platform", "debug");
GDVIRTUAL_BIND(_get_android_manifest_application_element_contents, "platform", "debug");
GDVIRTUAL_BIND(_get_android_manifest_element_contents, "platform", "debug");
+ GDVIRTUAL_BIND(_update_android_prebuilt_manifest, "platform", "manifest_data");
}
diff --git a/editor/export/editor_export_plugin.h b/editor/export/editor_export_plugin.h
index 6d60482687a9..5d60951b69c7 100644
--- a/editor/export/editor_export_plugin.h
+++ b/editor/export/editor_export_plugin.h
@@ -143,6 +143,7 @@ class EditorExportPlugin : public RefCounted {
GDVIRTUAL2RC(String, _get_android_manifest_activity_element_contents, const Ref &, bool);
GDVIRTUAL2RC(String, _get_android_manifest_application_element_contents, const Ref &, bool);
GDVIRTUAL2RC(String, _get_android_manifest_element_contents, const Ref &, bool);
+ GDVIRTUAL2RC(PackedByteArray, _update_android_prebuilt_manifest, const Ref &, const PackedByteArray &);
virtual bool _begin_customize_resources(const Ref &p_platform, const Vector &p_features); // Return true if this plugin does property export customization
virtual Ref _customize_resource(const Ref &p_resource, const String &p_path); // If nothing is returned, it means do not touch (nothing changed). If something is returned (either the same or a different resource) it means changes are made.
@@ -174,6 +175,7 @@ class EditorExportPlugin : public RefCounted {
virtual String get_android_manifest_activity_element_contents(const Ref &p_export_platform, bool p_debug) const;
virtual String get_android_manifest_application_element_contents(const Ref &p_export_platform, bool p_debug) const;
virtual String get_android_manifest_element_contents(const Ref &p_export_platform, bool p_debug) const;
+ virtual PackedByteArray update_android_prebuilt_manifest(const Ref &p_export_platform, const PackedByteArray &p_manifest_data) const;
Vector get_ios_frameworks() const;
Vector get_ios_embedded_frameworks() const;
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index cc2bdf8d7e71..7bb45c670add 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -30,7 +30,6 @@
#include "export_plugin.h"
-#include "gradle_export_util.h"
#include "logo_svg.gen.h"
#include "run_icon_svg.gen.h"
@@ -939,7 +938,7 @@ void EditorExportPlatformAndroid::_create_editor_debug_keystore_if_needed() {
print_verbose("Updated editor debug keystore to " + keystore_path);
}
-void EditorExportPlatformAndroid::_get_permissions(const Ref &p_preset, bool p_give_internet, Vector &r_permissions) {
+void EditorExportPlatformAndroid::_get_manifest_info(const Ref &p_preset, bool p_give_internet, Vector &r_permissions, Vector &r_features, Vector &r_metadata) {
const char **aperms = ANDROID_PERMS;
while (*aperms) {
bool enabled = p_preset->get("permissions/" + String(*aperms).to_lower());
@@ -960,6 +959,36 @@ void EditorExportPlatformAndroid::_get_permissions(const Ref
r_permissions.push_back("android.permission.INTERNET");
}
}
+
+ if (_uses_vulkan()) {
+ // Require vulkan hardware level 1 support
+ FeatureInfo vulkan_level = {
+ "android.hardware.vulkan.level", // name
+ false, // required
+ "1" // version
+ };
+ r_features.append(vulkan_level);
+
+ // Require vulkan version 1.0
+ FeatureInfo vulkan_version = {
+ "android.hardware.vulkan.version", // name
+ true, // required
+ "0x400003" // version - Encoded value for api version 1.0
+ };
+ r_features.append(vulkan_version);
+ }
+
+ MetadataInfo rendering_method_metadata = {
+ "org.godotengine.rendering.method",
+ GLOBAL_GET("rendering/renderer/rendering_method.mobile")
+ };
+ r_metadata.append(rendering_method_metadata);
+
+ MetadataInfo editor_version_metadata = {
+ "org.godotengine.editor.version",
+ String(VERSION_FULL_CONFIG)
+ };
+ r_metadata.append(editor_version_metadata);
}
void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref &p_preset, bool p_give_internet, bool p_debug) {
@@ -973,7 +1002,9 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref perms;
- _get_permissions(p_preset, p_give_internet, perms);
+ Vector features;
+ Vector manifest_metadata;
+ _get_manifest_info(p_preset, p_give_internet, perms, features, manifest_metadata);
for (int i = 0; i < perms.size(); i++) {
String permission = perms.get(i);
if (permission == "android.permission.WRITE_EXTERNAL_STORAGE" || (permission == "android.permission.READ_EXTERNAL_STORAGE" && _has_manage_external_storage_permission(perms))) {
@@ -983,9 +1014,8 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref\n";
- manifest_text += " \n";
+ for (int i = 0; i < features.size(); i++) {
+ manifest_text += vformat(" \n", features[i].name, features[i].required, features[i].version);
}
Vector[> export_plugins = EditorExport::get_singleton()->get_export_plugins();
@@ -999,7 +1029,7 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref(this), p_preset, _has_read_write_storage_permission(perms), p_debug);
+ manifest_text += _get_application_tag(Ref(this), p_preset, _has_read_write_storage_permission(perms), p_debug, manifest_metadata);
manifest_text += "\n";
String manifest_path = ExportTemplateManager::get_android_build_directory(p_preset).path_join(vformat("src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release")));
@@ -1101,8 +1131,9 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p
bool is_resizeable = bool(GLOBAL_GET("display/window/size/resizable"));
Vector perms;
- // Write permissions into the perms variable.
- _get_permissions(p_preset, p_give_internet, perms);
+ Vector features;
+ Vector manifest_metadata;
+ _get_manifest_info(p_preset, p_give_internet, perms, features, manifest_metadata);
bool has_read_write_storage_permission = _has_read_write_storage_permission(perms);
while (ofs < (uint32_t)p_manifest.size()) {
@@ -1246,42 +1277,25 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p
uint32_t name = decode_uint32(&p_manifest[iofs + 12]);
String tname = string_table[name];
- if (tname == "uses-feature") {
- Vector feature_names;
- Vector feature_required_list;
- Vector feature_versions;
-
- if (_uses_vulkan()) {
- // Require vulkan hardware level 1 support
- feature_names.push_back("android.hardware.vulkan.level");
- feature_required_list.push_back(false);
- feature_versions.push_back(1);
-
- // Require vulkan version 1.0
- feature_names.push_back("android.hardware.vulkan.version");
- feature_required_list.push_back(true);
- feature_versions.push_back(0x400003); // Encoded value for api version 1.0
- }
-
- if (feature_names.size() > 0) {
- ofs += 24; // skip over end tag
-
- // save manifest ending so we can restore it
- Vector manifest_end;
- uint32_t manifest_cur_size = p_manifest.size();
+ if (tname == "manifest" || tname == "application") {
+ // save manifest ending so we can restore it
+ Vector manifest_end;
+ uint32_t manifest_cur_size = p_manifest.size();
- manifest_end.resize(p_manifest.size() - ofs);
- memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
+ manifest_end.resize(p_manifest.size() - ofs);
+ memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
- int32_t attr_name_string = string_table.find("name");
- ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute.");
+ int32_t attr_name_string = string_table.find("name");
+ ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute.");
- int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android");
- if (ns_android_string == -1) {
- string_table.push_back("http://schemas.android.com/apk/res/android");
- ns_android_string = string_table.size() - 1;
- }
+ int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android");
+ if (ns_android_string == -1) {
+ string_table.push_back("http://schemas.android.com/apk/res/android");
+ ns_android_string = string_table.size() - 1;
+ }
+ if (tname == "manifest") {
+ // Updating manifest features
int32_t attr_uses_feature_string = string_table.find("uses-feature");
if (attr_uses_feature_string == -1) {
string_table.push_back("uses-feature");
@@ -1294,11 +1308,11 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p
attr_required_string = string_table.size() - 1;
}
- for (int i = 0; i < feature_names.size(); i++) {
- const String &feature_name = feature_names[i];
- bool feature_required = feature_required_list[i];
- int feature_version = feature_versions[i];
- bool has_version_attribute = feature_version != -1;
+ for (int i = 0; i < features.size(); i++) {
+ const String &feature_name = features[i].name;
+ bool feature_required = features[i].required;
+ String feature_version = features[i].version;
+ bool has_version_attribute = !feature_version.is_empty();
print_line("Adding feature " + feature_name);
@@ -1326,9 +1340,9 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p
attr_version_string = string_table.size() - 1;
}
- version_value = string_table.find(itos(feature_version));
+ version_value = string_table.find(feature_version);
if (version_value == -1) {
- string_table.push_back(itos(feature_version));
+ string_table.push_back(feature_version);
version_value = string_table.size() - 1;
}
@@ -1400,79 +1414,149 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p
ofs += 24;
}
- memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size());
- ofs -= 24; // go back over back end
- }
- }
- if (tname == "manifest") {
- // save manifest ending so we can restore it
- Vector manifest_end;
- uint32_t manifest_cur_size = p_manifest.size();
- manifest_end.resize(p_manifest.size() - ofs);
- memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
+ // Updating manifest permissions
+ int32_t attr_uses_permission_string = string_table.find("uses-permission");
+ if (attr_uses_permission_string == -1) {
+ string_table.push_back("uses-permission");
+ attr_uses_permission_string = string_table.size() - 1;
+ }
- int32_t attr_name_string = string_table.find("name");
- ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute.");
+ for (int i = 0; i < perms.size(); ++i) {
+ print_line("Adding permission " + perms[i]);
- int32_t ns_android_string = string_table.find("android");
- ERR_FAIL_COND_MSG(ns_android_string == -1, "Template does not have 'android' namespace.");
+ manifest_cur_size += 56 + 24; // node + end node
+ p_manifest.resize(manifest_cur_size);
- int32_t attr_uses_permission_string = string_table.find("uses-permission");
- if (attr_uses_permission_string == -1) {
- string_table.push_back("uses-permission");
- attr_uses_permission_string = string_table.size() - 1;
- }
+ // Add permission to the string pool
+ int32_t perm_string = string_table.find(perms[i]);
+ if (perm_string == -1) {
+ string_table.push_back(perms[i]);
+ perm_string = string_table.size() - 1;
+ }
- for (int i = 0; i < perms.size(); ++i) {
- print_line("Adding permission " + perms[i]);
+ // start tag
+ encode_uint16(0x102, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(56, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+ encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start
+ encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size
+ encode_uint16(1, &p_manifest.write[ofs + 28]); // num_attrs
+ encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index
+ encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index
+ encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index
+
+ // attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns
+ encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name'
+ encode_uint32(perm_string, &p_manifest.write[ofs + 44]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size
+ p_manifest.write[ofs + 50] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string)
+ encode_uint32(perm_string, &p_manifest.write[ofs + 52]); // typedvalue reference
- manifest_cur_size += 56 + 24; // node + end node
- p_manifest.resize(manifest_cur_size);
+ ofs += 56;
- // Add permission to the string pool
- int32_t perm_string = string_table.find(perms[i]);
- if (perm_string == -1) {
- string_table.push_back(perms[i]);
- perm_string = string_table.size() - 1;
+ // end tag
+ encode_uint16(0x103, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(24, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
+
+ ofs += 24;
+ }
+ }
+
+ if (tname == "application") {
+ // Updating application meta-data
+ int32_t attr_meta_data_string = string_table.find("meta-data");
+ if (attr_meta_data_string == -1) {
+ string_table.push_back("meta-data");
+ attr_meta_data_string = string_table.size() - 1;
}
- // start tag
- encode_uint16(0x102, &p_manifest.write[ofs]); // type
- encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
- encode_uint32(56, &p_manifest.write[ofs + 4]); // size
- encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
- encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
- encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
- encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
- encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start
- encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size
- encode_uint16(1, &p_manifest.write[ofs + 28]); // num_attrs
- encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index
- encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index
- encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index
-
- // attribute
- encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns
- encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name'
- encode_uint32(perm_string, &p_manifest.write[ofs + 44]); // raw_value
- encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size
- p_manifest.write[ofs + 50] = 0; // typedvalue_always0
- p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string)
- encode_uint32(perm_string, &p_manifest.write[ofs + 52]); // typedvalue reference
-
- ofs += 56;
-
- // end tag
- encode_uint16(0x103, &p_manifest.write[ofs]); // type
- encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
- encode_uint32(24, &p_manifest.write[ofs + 4]); // size
- encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
- encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
- encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
- encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name
-
- ofs += 24;
+ int32_t attr_value_string = string_table.find("value");
+ if (attr_value_string == -1) {
+ string_table.push_back("value");
+ attr_value_string = string_table.size() - 1;
+ }
+
+ for (int i = 0; i < manifest_metadata.size(); i++) {
+ String meta_data_name = manifest_metadata[i].name;
+ String meta_data_value = manifest_metadata[i].value;
+
+ print_line("Adding application metadata " + meta_data_name);
+
+ int32_t meta_data_name_string = string_table.find(meta_data_name);
+ if (meta_data_name_string == -1) {
+ string_table.push_back(meta_data_name);
+ meta_data_name_string = string_table.size() - 1;
+ }
+
+ int32_t meta_data_value_string = string_table.find(meta_data_value);
+ if (meta_data_value_string == -1) {
+ string_table.push_back(meta_data_value);
+ meta_data_value_string = string_table.size() - 1;
+ }
+
+ int tag_size = 76; // node and two attrs + end node
+ int attr_count = 2;
+ manifest_cur_size += tag_size + 24;
+ p_manifest.resize(manifest_cur_size);
+
+ // start tag
+ encode_uint16(0x102, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(tag_size, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_meta_data_string, &p_manifest.write[ofs + 20]); // name
+ encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start
+ encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size
+ encode_uint16(attr_count, &p_manifest.write[ofs + 28]); // num_attrs
+ encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index
+ encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index
+ encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index
+
+ // android:name attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns
+ encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name'
+ encode_uint32(meta_data_name_string, &p_manifest.write[ofs + 44]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size
+ p_manifest.write[ofs + 50] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string)
+ encode_uint32(meta_data_name_string, &p_manifest.write[ofs + 52]); // typedvalue reference
+
+ // android:value attribute
+ encode_uint32(ns_android_string, &p_manifest.write[ofs + 56]); // ns
+ encode_uint32(attr_value_string, &p_manifest.write[ofs + 60]); // 'value'
+ encode_uint32(meta_data_value_string, &p_manifest.write[ofs + 64]); // raw_value
+ encode_uint16(8, &p_manifest.write[ofs + 68]); // typedvalue_size
+ p_manifest.write[ofs + 70] = 0; // typedvalue_always0
+ p_manifest.write[ofs + 71] = 0x03; // typedvalue_type (string)
+ encode_uint32(meta_data_value_string, &p_manifest.write[ofs + 72]); // typedvalue reference
+
+ ofs += 76;
+
+ // end tag
+ encode_uint16(0x103, &p_manifest.write[ofs]); // type
+ encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize
+ encode_uint32(24, &p_manifest.write[ofs + 4]); // size
+ encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns
+ encode_uint32(attr_meta_data_string, &p_manifest.write[ofs + 20]); // name
+
+ ofs += 24;
+ }
}
// copy footer back in
@@ -1484,7 +1568,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p
ofs += size;
}
- //create new andriodmanifest binary
+ // Create new android manifest binary.
Vector ret;
ret.resize(string_table_begins + string_table.size() * 4);
@@ -1864,16 +1948,10 @@ String EditorExportPlatformAndroid::get_export_option_warning(const EditorExport
}
} else if (p_name == "gradle_build/use_gradle_build") {
bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build");
- String enabled_plugins_names = _get_plugins_names(Ref(p_preset));
- if (!enabled_plugins_names.is_empty() && !gradle_build_enabled) {
+ String enabled_deprecated_plugins_names = _get_deprecated_plugins_names(Ref(p_preset));
+ if (!enabled_deprecated_plugins_names.is_empty() && !gradle_build_enabled) {
return TTR("\"Use Gradle Build\" must be enabled to use the plugins.");
}
- } else if (p_name == "xr_features/xr_mode") {
- bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build");
- int xr_mode_index = p_preset->get("xr_features/xr_mode");
- if (xr_mode_index == XR_MODE_OPENXR && !gradle_build_enabled) {
- return TTR("OpenXR requires \"Use Gradle Build\" to be enabled");
- }
} else if (p_name == "gradle_build/compress_native_libraries") {
bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build");
if (bool(p_preset->get("gradle_build/compress_native_libraries")) && !gradle_build_enabled) {
@@ -2602,6 +2680,7 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Ref &p_preset) const {
+ Vector names;
+
+#ifndef DISABLE_DEPRECATED
+ PluginConfigAndroid::get_plugins_names(get_enabled_plugins(p_preset), names);
+#endif // DISABLE_DEPRECATED
+
+ String plugins_names = String("|").join(names);
+ return plugins_names;
+}
+
String EditorExportPlatformAndroid::_get_plugins_names(const Ref &p_preset) const {
Vector names;
@@ -3459,7 +3550,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Refglobalize_path("res://addons");
- String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method.mobile");
cmdline.push_back("-p"); // argument to specify the start directory.
cmdline.push_back(build_path); // start directory.
@@ -3476,8 +3566,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref> export_plugins = EditorExport::get_singleton()->get_export_plugins();
+ for (int i = 0; i < export_plugins.size(); i++) {
+ if (export_plugins[i]->supports_platform(Ref(this))) {
+ PackedByteArray export_plugin_data = export_plugins[i]->update_android_prebuilt_manifest(Ref(this), data);
+ if (!export_plugin_data.is_empty()) {
+ data = export_plugin_data;
+ }
+ }
+ }
}
if (file == "resources.arsc") {
_fix_resources(p_preset, data);
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index 4b4753482169..585b1c4b687b 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -34,6 +34,8 @@
#include "godot_plugin_config.h"
#endif // DISABLE_DEPRECATED
+#include "gradle_export_util.h"
+
#include "core/io/image.h"
#include "core/io/zip_io.h"
#include "core/os/os.h"
@@ -75,6 +77,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
EditorProgress *ep = nullptr;
};
+ struct FeatureInfo {
+ String name;
+ bool required;
+ String version = "";
+ };
+
#ifndef DISABLE_DEPRECATED
mutable Vector android_plugins;
mutable SafeFlag android_plugins_changed;
@@ -151,7 +159,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bool _has_manage_external_storage_permission(const Vector &p_permissions);
- void _get_permissions(const Ref &p_preset, bool p_give_internet, Vector &r_permissions);
+ void _get_manifest_info(const Ref &p_preset, bool p_give_internet, Vector &r_permissions, Vector &r_features, Vector &r_metadata);
void _write_tmp_manifest(const Ref &p_preset, bool p_give_internet, bool p_debug);
@@ -235,6 +243,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
virtual List get_binary_extensions(const Ref &p_preset) const override;
+ String _get_deprecated_plugins_names(const Ref &p_preset) const;
+
String _get_plugins_names(const Ref &p_preset) const;
String _resolve_export_plugin_android_library_path(const String &p_android_library_path) const;
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 32ad2d44066c..2251a276924e 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -306,7 +306,7 @@ String _get_activity_tag(const Ref &p_export_platform, con
return manifest_activity_text;
}
-String _get_application_tag(const Ref &p_export_platform, const Ref &p_preset, bool p_has_read_write_storage_permission, bool p_debug) {
+String _get_application_tag(const Ref &p_export_platform, const Ref &p_preset, bool p_has_read_write_storage_permission, bool p_debug, const Vector &p_metadata) {
int app_category_index = (int)(p_preset->get("package/app_category"));
bool is_game = app_category_index == APP_CATEGORY_GAME;
@@ -330,6 +330,10 @@ String _get_application_tag(const Ref &p_export_platform,
}
manifest_application_text += " tools:ignore=\"GoogleAppIndexingWarning\">\n\n";
+ for (int i = 0; i < p_metadata.size(); i++) {
+ manifest_application_text += vformat(" \n", p_metadata[i].name, p_metadata[i].value);
+ }
+
Vector][> export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->supports_platform(p_export_platform)) {
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index ee95f03ea4dd..340902432a39 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -68,6 +68,11 @@ struct CustomExportData {
Vector libs;
};
+struct MetadataInfo {
+ String name;
+ String value;
+};
+
int _get_android_orientation_value(DisplayServer::ScreenOrientation screen_orientation);
String _get_android_orientation_label(DisplayServer::ScreenOrientation screen_orientation);
@@ -105,4 +110,4 @@ String _get_screen_sizes_tag(const Ref &p_preset);
String _get_activity_tag(const Ref &p_export_platform, const Ref &p_preset, bool p_debug);
-String _get_application_tag(const Ref &p_export_platform, const Ref &p_preset, bool p_has_read_write_storage_permission, bool p_debug);
+String _get_application_tag(const Ref &p_export_platform, const Ref &p_preset, bool p_has_read_write_storage_permission, bool p_debug, const Vector &p_metadata);
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index 1d59d15d560f..e99aaa4a8d9a 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -29,15 +29,6 @@
android:enabled="true"
tools:targetApi="29" />
-
-
-
-
-
}
}
-ext.getGodotRenderingMethod = { ->
- String renderingMethod = project.hasProperty("godot_rendering_method") ? project.property("godot_rendering_method") : ""
- return renderingMethod
-}
-
-ext.getGodotEditorVersion = { ->
- String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : ""
- if (editorVersion == null || editorVersion.isEmpty()) {
- // Try the library version first
- editorVersion = getGodotLibraryVersionName()
-
- if (editorVersion.isEmpty()) {
- // Fallback value.
- editorVersion = "custom_build"
- }
- }
- return editorVersion
-}
-
ext.getGodotLibraryVersionCode = { ->
String versionName = ""
int versionCode = 1
diff --git a/platform/android/java/editor/src/horizonos/AndroidManifest.xml b/platform/android/java/editor/src/horizonos/AndroidManifest.xml
index 3f2b87e04852..3db83340aa1f 100644
--- a/platform/android/java/editor/src/horizonos/AndroidManifest.xml
+++ b/platform/android/java/editor/src/horizonos/AndroidManifest.xml
@@ -90,6 +90,8 @@
+
+
]