summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/linux_builds.yml2
-rw-r--r--.github/workflows/macos_builds.yml2
-rw-r--r--.github/workflows/windows_builds.yml2
-rw-r--r--README.md2
-rw-r--r--SConstruct14
-rw-r--r--core/object.cpp2
-rw-r--r--editor/editor_autoload_settings.cpp4
-rw-r--r--editor/input_map_editor.cpp70
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp4
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp2
-rw-r--r--editor/scene_tree_dock.cpp2
-rw-r--r--editor/script_create_dialog.cpp4
-rw-r--r--main/SCsub2
-rw-r--r--main/main.cpp10
-rw-r--r--platform/android/export/export.cpp41
-rw-r--r--platform/android/export/gradle_export_util.h100
-rw-r--r--platform/android/java/app/build.gradle2
-rw-r--r--platform/android/java/app/config.gradle16
20 files changed, 224 insertions, 61 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index be7737593a..a05bb09931 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -60,7 +60,7 @@ jobs:
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
- scons -j2 verbose=yes warnings=all werror=yes platform=linuxbsd tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
+ scons -j2 verbose=yes warnings=all werror=yes platform=linuxbsd tools=yes tests=yes target=release_debug module_mono_enabled=yes mono_glue=no
# Execute unit tests for the editor
- name: Unit Tests
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml
index 4a9fa910d0..56a4343bbe 100644
--- a/.github/workflows/macos_builds.yml
+++ b/.github/workflows/macos_builds.yml
@@ -49,7 +49,7 @@ jobs:
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
- scons -j2 verbose=yes warnings=all werror=yes platform=osx tools=yes target=release_debug
+ scons -j2 verbose=yes warnings=all werror=yes platform=osx tools=yes tests=yes target=release_debug
# Execute unit tests for the editor
- name: Unit Tests
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml
index c58bae8275..2bc3fcfdaa 100644
--- a/.github/workflows/windows_builds.yml
+++ b/.github/workflows/windows_builds.yml
@@ -54,7 +54,7 @@ jobs:
env:
SCONS_CACHE: /.scons_cache/
run: |
- scons -j2 verbose=yes warnings=all werror=yes platform=windows tools=yes target=release_debug
+ scons -j2 verbose=yes warnings=all werror=yes platform=windows tools=yes tests=yes target=release_debug
# Execute unit tests for the editor
- name: Unit Tests
diff --git a/README.md b/README.md
index 5cfa10c5dd..e962f90333 100644
--- a/README.md
+++ b/README.md
@@ -66,9 +66,7 @@ There are also a number of other learning resources provided by the community,
such as text and video tutorials, demos, etc. Consult the [community channels](https://godotengine.org/community)
for more info.
-[![Travis Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
[![Actions Build Status](https://github.com/godotengine/godot/workflows/Godot/badge.svg?branch=master)](https://github.com/godotengine/godot/actions)
-[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bfiihqq6byxsjxxh/branch/master?svg=true)](https://ci.appveyor.com/project/akien-mga/godot)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
diff --git a/SConstruct b/SConstruct
index e23aa1cdbc..debae3c9df 100644
--- a/SConstruct
+++ b/SConstruct
@@ -115,6 +115,7 @@ opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "releas
opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size")))
opts.Add(BoolVariable("tools", "Build the tools (a.k.a. the Godot editor)", True))
+opts.Add(BoolVariable("tests", "Build the unit tests", False))
opts.Add(BoolVariable("use_lto", "Use link-time optimization", False))
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
@@ -249,6 +250,10 @@ if env_base["target"] == "debug":
# http://scons.org/doc/production/HTML/scons-user/ch06s04.html
env_base.SetOption("implicit_cache", 1)
+if not env_base["tools"]:
+ # Export templates can't run unit test tool.
+ env_base["tests"] = False
+
if env_base["no_editor_splash"]:
env_base.Append(CPPDEFINES=["NO_EDITOR_SPLASH"])
@@ -312,6 +317,8 @@ if selected_platform in platform_list:
env["verbose"] = True
env["warnings"] = "extra"
env["werror"] = True
+ if env["tools"]:
+ env["tests"] = True
if env["vsproj"]:
env.vs_incs = []
@@ -586,6 +593,8 @@ if selected_platform in platform_list:
env.Append(CPPDEFINES=["PTRCALL_ENABLED"])
if env["tools"]:
env.Append(CPPDEFINES=["TOOLS_ENABLED"])
+ if env["tests"]:
+ env.Append(CPPDEFINES=["TESTS_ENABLED"])
if env["disable_3d"]:
if env["tools"]:
print(
@@ -641,8 +650,9 @@ if selected_platform in platform_list:
}
)
- # enable test framework globally and inform it of configuration method
- env.Append(CPPDEFINES=["DOCTEST_CONFIG_IMPLEMENT"])
+ # Enable test framework globally and inform it of configuration method.
+ if env["tests"]:
+ env.Append(CPPDEFINES=["DOCTEST_CONFIG_IMPLEMENT"])
scons_cache_path = os.environ.get("SCONS_CACHE")
if scons_cache_path != None:
diff --git a/core/object.cpp b/core/object.cpp
index 8abea9ca7e..ba002024e6 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -675,7 +675,7 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Call
StringName method = *p_args[0];
- MessageQueue::get_singleton()->push_call(get_instance_id(), method, &p_args[1], p_argcount - 1);
+ MessageQueue::get_singleton()->push_call(get_instance_id(), method, &p_args[1], p_argcount - 1, true);
return Variant();
}
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 94887fb848..5d101ff2c2 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -688,12 +688,12 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_
const String &path = p_path;
if (!FileAccess::exists(path)) {
- EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + TTR(vformat("%s is an invalid path. File does not exist.", path)));
+ EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + vformat(TTR("%s is an invalid path. File does not exist."), path));
return false;
}
if (!path.begins_with("res://")) {
- EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + TTR(vformat("%s is an invalid path. Not in resource path (res://).", path)));
+ EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + vformat(TTR("%s is an invalid path. Not in resource path (res://)."), path));
return false;
}
diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp
index 70c354e55a..52cf9c1869 100644
--- a/editor/input_map_editor.cpp
+++ b/editor/input_map_editor.cpp
@@ -36,44 +36,44 @@
#include "editor/editor_scale.h"
static const char *_button_descriptions[JOY_SDL_BUTTONS] = {
- "Face Bottom, DualShock Cross, Xbox A, Nintendo B",
- "Face Right, DualShock Circle, Xbox B, Nintendo A",
- "Face Left, DualShock Square, Xbox X, Nintendo Y",
- "Face Top, DualShock Triangle, Xbox Y, Nintendo X",
- "DualShock Select, Xbox Back, Nintendo -",
- "Home, DualShock PS, Guide",
- "Start, Nintendo +",
- "Left Stick, DualShock L3, Xbox L/LS",
- "Right Stick, DualShock R3, Xbox R/RS",
- "Left Shoulder, DualShock L1, Xbox LB",
- "Right Shoulder, DualShock R1, Xbox RB",
- "D-Pad Up",
- "D-Pad Down",
- "D-Pad Left",
- "D-Pad Right"
+ TTRC("Face Bottom, DualShock Cross, Xbox A, Nintendo B"),
+ TTRC("Face Right, DualShock Circle, Xbox B, Nintendo A"),
+ TTRC("Face Left, DualShock Square, Xbox X, Nintendo Y"),
+ TTRC("Face Top, DualShock Triangle, Xbox Y, Nintendo X"),
+ TTRC("DualShock Select, Xbox Back, Nintendo -"),
+ TTRC("Home, DualShock PS, Guide"),
+ TTRC("Start, Nintendo +"),
+ TTRC("Left Stick, DualShock L3, Xbox L/LS"),
+ TTRC("Right Stick, DualShock R3, Xbox R/RS"),
+ TTRC("Left Shoulder, DualShock L1, Xbox LB"),
+ TTRC("Right Shoulder, DualShock R1, Xbox RB"),
+ TTRC("D-Pad Up"),
+ TTRC("D-Pad Down"),
+ TTRC("D-Pad Left"),
+ TTRC("D-Pad Right")
};
static const char *_axis_descriptions[JOY_AXIS_MAX * 2] = {
- "Left Stick Left",
- "Left Stick Right",
- "Left Stick Up",
- "Left Stick Down",
- "Right Stick Left",
- "Right Stick Right",
- "Right Stick Up",
- "Right Stick Down",
- "Joystick 2 Left",
- "Joystick 2 Right, Left Trigger, L2, LT",
- "Joystick 2 Up",
- "Joystick 2 Down, Right Trigger, R2, RT",
- "Joystick 3 Left",
- "Joystick 3 Right",
- "Joystick 3 Up",
- "Joystick 3 Down",
- "Joystick 4 Left",
- "Joystick 4 Right",
- "Joystick 4 Up",
- "Joystick 4 Down",
+ TTRC("Left Stick Left"),
+ TTRC("Left Stick Right"),
+ TTRC("Left Stick Up"),
+ TTRC("Left Stick Down"),
+ TTRC("Right Stick Left"),
+ TTRC("Right Stick Right"),
+ TTRC("Right Stick Up"),
+ TTRC("Right Stick Down"),
+ TTRC("Joystick 2 Left"),
+ TTRC("Joystick 2 Right, Left Trigger, L2, LT"),
+ TTRC("Joystick 2 Up"),
+ TTRC("Joystick 2 Down, Right Trigger, R2, RT"),
+ TTRC("Joystick 3 Left"),
+ TTRC("Joystick 3 Right"),
+ TTRC("Joystick 3 Up"),
+ TTRC("Joystick 3 Down"),
+ TTRC("Joystick 4 Left"),
+ TTRC("Joystick 4 Right"),
+ TTRC("Joystick 4 Up"),
+ TTRC("Joystick 4 Down"),
};
void InputMapEditor::_notification(int p_what) {
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index e2f35e29d8..af1d266832 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -411,7 +411,7 @@ void AnimationPlayerEditor::_animation_remove() {
String current = animation->get_item_text(animation->get_selected());
- delete_dialog->set_text(TTR("Delete Animation '" + current + "'?"));
+ delete_dialog->set_text(vformat(TTR("Delete Animation '%s'?"), current));
delete_dialog->popup_centered();
}
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index ced0b9f984..6f209c512e 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -5407,7 +5407,7 @@ void Node3DEditor::_update_gizmos_menu() {
}
String plugin_name = gizmo_plugins_by_name[i]->get_name();
const int plugin_state = gizmo_plugins_by_name[i]->get_state();
- gizmos_menu->add_multistate_item(TTR(plugin_name), 3, plugin_state, i);
+ gizmos_menu->add_multistate_item(plugin_name, 3, plugin_state, i);
const int idx = gizmos_menu->get_item_index(i);
gizmos_menu->set_item_tooltip(
idx,
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 71830d0464..00fee90841 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1577,7 +1577,9 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
List<int> bpoints;
se->get_breakpoints(&bpoints);
String base = script->get_path();
- ERR_CONTINUE(base.begins_with("local://") || base == "");
+ if (base.begins_with("local://") || base == "") {
+ continue;
+ }
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
p_breakpoints->push_back(base + ":" + itos(E->get() + 1));
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 7fb751e3ed..a613174ed9 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -698,7 +698,7 @@ void TileSetEditor::_on_tileset_toolbar_confirm() {
List<int> ids;
tileset->get_tile_list(&ids);
- undo_redo->create_action(TTR(option == TOOL_TILESET_MERGE_SCENE ? "Merge Tileset from Scene" : "Create Tileset from Scene"));
+ undo_redo->create_action(option == TOOL_TILESET_MERGE_SCENE ? TTR("Merge Tileset from Scene") : TTR("Create Tileset from Scene"));
undo_redo->add_do_method(this, "_undo_redo_import_scene", scene, option == TOOL_TILESET_MERGE_SCENE);
undo_redo->add_undo_method(tileset.ptr(), "clear");
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 108e44f294..ce869feddd 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2718,7 +2718,7 @@ void SceneTreeDock::_update_create_root_dialog() {
if (l != String()) {
Button *button = memnew(Button);
favorite_nodes->add_child(button);
- button->set_text(TTR(l));
+ button->set_text(l);
String name = l.get_slicec(' ', 0);
if (ScriptServer::is_global_class(name)) {
name = ScriptServer::get_global_class_native_base(name);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index ffdf8208b8..628475bbc0 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -603,7 +603,7 @@ void ScriptCreateDialog::_path_entered(const String &p_path) {
}
void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
- error_label->set_text("- " + TTR(p_msg));
+ error_label->set_text("- " + p_msg);
if (valid) {
error_label->add_theme_color_override("font_color", gc->get_theme_color("success_color", "Editor"));
} else {
@@ -612,7 +612,7 @@ void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
}
void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
- path_error_label->set_text("- " + TTR(p_msg));
+ path_error_label->set_text("- " + p_msg);
if (valid) {
path_error_label->add_theme_color_override("font_color", gc->get_theme_color("success_color", "Editor"));
} else {
diff --git a/main/SCsub b/main/SCsub
index bf188d7328..793e5ed827 100644
--- a/main/SCsub
+++ b/main/SCsub
@@ -20,7 +20,7 @@ env.CommandNoCache(
env.Depends("#main/app_icon.gen.h", "#main/app_icon.png")
env.CommandNoCache("#main/app_icon.gen.h", "#main/app_icon.png", run_in_subprocess(main_builders.make_app_icon))
-if env["tools"]:
+if env["tests"]:
SConscript("tests/SCsub")
lib = env.add_library("main", env.main_sources)
diff --git a/main/main.cpp b/main/main.cpp
index 35aa99c720..60abed7b0b 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -55,7 +55,6 @@
#include "main/performance.h"
#include "main/splash.gen.h"
#include "main/splash_editor.gen.h"
-#include "main/tests/test_main.h"
#include "modules/modules_enabled.gen.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
@@ -75,6 +74,10 @@
#include "servers/rendering/rendering_server_wrap_mt.h"
#include "servers/xr_server.h"
+#ifdef TESTS_ENABLED
+#include "main/tests/test_main.h"
+#endif
+
#ifdef TOOLS_ENABLED
#include "editor/doc_data.h"
@@ -383,6 +386,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(
" --gdnative-generate-json-api Generate JSON dump of the Godot API for GDNative bindings.\n");
#endif
+#ifdef TESTS_ENABLED
OS::get_singleton()->print(" --test <test> Run a unit test [");
const char **test_names = tests_get_names();
const char *comma = "";
@@ -393,10 +397,12 @@ void Main::print_help(const char *p_binary) {
}
OS::get_singleton()->print("].\n");
#endif
+ OS::get_singleton()->print("\n");
+#endif
}
int Main::test_entrypoint(int argc, char *argv[], bool &tests_need_run) {
-#ifdef TOOLS_ENABLED // templates can't run unit test tool
+#ifdef TESTS_ENABLED
for (int x = 0; x < argc; x++) {
if (strncmp(argv[x], "--test", 6) == 0) {
tests_need_run = true;
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 0213094c60..8d3257a365 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -768,6 +768,30 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
}
+ void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) {
+ String manifest_text =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
+ " xmlns:tools=\"http://schemas.android.com/tools\">\n";
+
+ manifest_text += _get_screen_sizes_tag(p_preset);
+ manifest_text += _get_gles_tag();
+
+ Vector<String> perms;
+ _get_permissions(p_preset, p_give_internet, perms);
+ for (int i = 0; i < perms.size(); i++) {
+ manifest_text += vformat(" <uses-permission android:name=\"%s\" />\n", perms.get(i));
+ }
+
+ manifest_text += _get_xr_features_tag(p_preset);
+ manifest_text += _get_instrumentation_tag(p_preset);
+ String plugins_names = get_plugins_names(get_enabled_plugins(p_preset));
+ manifest_text += _get_application_tag(p_preset, plugins_names);
+ manifest_text += "</manifest>\n";
+ String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release"));
+ store_string_at_path(manifest_path, manifest_text);
+ }
+
void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet) {
// Leaving the unused types commented because looking these constants up
// again later would be annoying
@@ -2064,6 +2088,7 @@ public:
EditorProgress ep("export", "Exporting for Android", 105, true);
bool use_custom_build = bool(p_preset->get("custom_template/use_custom_build"));
+ bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
Ref<Image> main_image;
Ref<Image> foreground;
@@ -2093,9 +2118,10 @@ public:
if (err != OK) {
EditorNode::add_io_error("Unable to overwrite res://android/build/res/*.xml files with project name");
}
- // Copies the project icon files into the appropriate Gradle project directory
+ // Copies the project icon files into the appropriate Gradle project directory.
_copy_icons_to_gradle_project(p_preset, main_image, foreground, background);
-
+ // Write an AndroidManifest.xml file into the Gradle project directory.
+ _write_tmp_manifest(p_preset, p_give_internet, p_debug);
//build project if custom build is enabled
String sdk_path = EDITOR_GET("export/android/custom_build_sdk_path");
@@ -2115,6 +2141,8 @@ public:
build_command = build_path.plus_file(build_command);
String package_name = get_package_name(p_preset->get("package/unique_name"));
+ String version_code = itos(p_preset->get("version/code"));
+ String version_name = p_preset->get("version/name");
Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset);
String local_plugins_binaries = get_plugins_binaries(BINARY_TYPE_LOCAL, enabled_plugins);
@@ -2128,6 +2156,8 @@ public:
}
cmdline.push_back("build");
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
+ cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code.
+ cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name.
cmdline.push_back("-Pplugins_local_binaries=" + local_plugins_binaries); // argument to specify the list of plugins local dependencies.
cmdline.push_back("-Pplugins_remote_binaries=" + remote_plugins_binaries); // argument to specify the list of plugins remote dependencies.
cmdline.push_back("-Pplugins_maven_repos=" + custom_maven_repos); // argument to specify the list of custom maven repos for the plugins dependencies.
@@ -2248,11 +2278,10 @@ public:
//write
- if (file == "AndroidManifest.xml") {
- _fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG));
- }
-
if (!use_custom_build) {
+ if (file == "AndroidManifest.xml") {
+ _fix_manifest(p_preset, data, p_give_internet);
+ }
if (file == "resources.arsc") {
_fix_resources(p_preset, data);
}
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index 622860c307..209a664f8f 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -142,4 +142,104 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset
return OK;
}
+String bool_to_string(bool v) {
+ return v ? "true" : "false";
+}
+
+String _get_gles_tag() {
+ bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES3" &&
+ !ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2");
+ return min_gles3 ? " <uses-feature android:glEsVersion=\"0x00030000\" android:required=\"true\" />\n" : "";
+}
+
+String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) {
+ String manifest_screen_sizes = " <supports-screens \n tools:node=\"replace\"";
+ String sizes[] = { "small", "normal", "large", "xlarge" };
+ size_t num_sizes = sizeof(sizes) / sizeof(sizes[0]);
+ for (size_t i = 0; i < num_sizes; i++) {
+ String feature_name = vformat("screen/support_%s", sizes[i]);
+ String feature_support = bool_to_string(p_preset->get(feature_name));
+ String xml_entry = vformat("\n android:%sScreens=\"%s\"", sizes[i], feature_support);
+ manifest_screen_sizes += xml_entry;
+ }
+ manifest_screen_sizes += " />\n";
+ return manifest_screen_sizes;
+}
+
+String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
+ String manifest_xr_features;
+ bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
+ if (uses_xr) {
+ int dof_index = p_preset->get("xr_features/degrees_of_freedom"); // 0: none, 1: 3dof and 6dof, 2: 6dof
+ if (dof_index == 1) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"false\" android:version=\"1\" />\n";
+ } else if (dof_index == 2) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n";
+ }
+ int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
+ if (hand_tracking_index == 1) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n";
+ } else if (hand_tracking_index == 2) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"true\" />\n";
+ }
+ }
+ return manifest_xr_features;
+}
+
+String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) {
+ String package_name = p_preset->get("package/unique_name");
+ String manifest_instrumentation_text = vformat(
+ " <instrumentation\n"
+ " tools:node=\"replace\"\n"
+ " android:name=\".GodotInstrumentation\"\n"
+ " android:icon=\"@mipmap/icon\"\n"
+ " android:label=\"@string/godot_project_name_string\"\n"
+ " android:targetPackage=\"%s\" />\n",
+ package_name);
+ return manifest_instrumentation_text;
+}
+
+String _get_plugins_tag(const String &plugins_names) {
+ if (!plugins_names.empty()) {
+ return vformat(" <meta-data tools:node=\"replace\" android:name=\"plugins\" android:value=\"%s\" />\n", plugins_names);
+ } else {
+ return " <meta-data tools:node=\"remove\" android:name=\"plugins\" />\n";
+ }
+}
+
+String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
+ bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
+ String orientation = (int)(p_preset->get("screen/orientation")) == 1 ? "portrait" : "landscape";
+ String manifest_activity_text = vformat(
+ " <activity android:name=\"com.godot.game.GodotApp\" "
+ "tools:replace=\"android:screenOrientation\" "
+ "android:screenOrientation=\"%s\">\n",
+ orientation);
+ if (uses_xr) {
+ String focus_awareness = bool_to_string(p_preset->get("xr_features/focus_awareness"));
+ manifest_activity_text += vformat(" <meta-data tools:node=\"replace\" android:name=\"com.oculus.vr.focusaware\" android:value=\"%s\" />\n", focus_awareness);
+ } else {
+ manifest_activity_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.vr.focusaware\" />\n";
+ }
+ manifest_activity_text += " </activity>\n";
+ return manifest_activity_text;
+}
+
+String _get_application_tag(const Ref<EditorExportPreset> &p_preset, const String &plugins_names) {
+ bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
+ String manifest_application_text =
+ " <application android:label=\"@string/godot_project_name_string\"\n"
+ " android:allowBackup=\"false\" tools:ignore=\"GoogleAppIndexingWarning\"\n"
+ " android:icon=\"@mipmap/icon\">)\n\n"
+ " <meta-data tools:node=\"remove\" android:name=\"xr_mode_metadata_name\" />\n";
+
+ manifest_application_text += _get_plugins_tag(plugins_names);
+ if (uses_xr) {
+ manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
+ }
+ manifest_application_text += _get_activity_tag(p_preset);
+ manifest_application_text += " </application>\n";
+ return manifest_application_text;
+}
+
#endif //GODOT_GRADLE_EXPORT_UTIL_H
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 19202d2310..3f8d138e8f 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -82,6 +82,8 @@ android {
// Feel free to modify the application id to your own.
applicationId getExportPackageName()
+ versionCode getExportVersionCode()
+ versionName getExportVersionName()
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index acfdef531e..7d5d238100 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -28,6 +28,22 @@ ext.getExportPackageName = { ->
return appId
}
+ext.getExportVersionCode = { ->
+ String versionCode = project.hasProperty("export_version_code") ? project.property("export_version_code") : ""
+ if (versionCode == null || versionCode.isEmpty()) {
+ versionCode = "1"
+ }
+ return Integer.parseInt(versionCode)
+}
+
+ext.getExportVersionName = { ->
+ String versionName = project.hasProperty("export_version_name") ? project.property("export_version_name") : ""
+ if (versionName == null || versionName.isEmpty()) {
+ versionName = "1.0"
+ }
+ return versionName
+}
+
final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|"
/**