summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/android_input_handler.cpp10
-rw-r--r--platform/android/android_input_handler.h2
-rw-r--r--platform/android/detect.py332
-rw-r--r--platform/android/export/export_plugin.cpp71
-rw-r--r--platform/android/java/app/AndroidManifest.xml1
-rw-r--r--platform/android/java/app/build.gradle13
-rw-r--r--platform/android/java/app/config.gradle11
-rw-r--r--platform/android/java/app/settings.gradle13
-rw-r--r--platform/android/java/build.gradle11
-rw-r--r--platform/android/java/editor/build.gradle11
-rw-r--r--platform/android/java/editor/src/main/AndroidManifest.xml9
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java124
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt146
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java)10
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java)9
-rw-r--r--platform/android/java/editor/src/main/res/values/dimens.xml5
-rw-r--r--platform/android/java/lib/AndroidManifest.xml2
-rw-r--r--platform/android/java/lib/build.gradle10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java24
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java5
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java9
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java3
-rw-r--r--platform/android/java/nativeSrcsConfigs/build.gradle5
-rw-r--r--platform/android/java/settings.gradle15
-rw-r--r--platform/android/java_godot_lib_jni.cpp9
-rw-r--r--platform/android/java_godot_lib_jni.h1
26 files changed, 382 insertions, 479 deletions
diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp
index 10f23b320b..81802298d9 100644
--- a/platform/android/android_input_handler.cpp
+++ b/platform/android/android_input_handler.cpp
@@ -381,13 +381,3 @@ MouseButton AndroidInputHandler::_android_button_mask_to_godot_button_mask(int a
return godot_button_mask;
}
-
-void AndroidInputHandler::process_scroll(Point2 p_pos) {
- Ref<InputEventPanGesture> ev;
- ev.instantiate();
- _set_key_modifier_state(ev);
- ev->set_position(p_pos);
- ev->set_delta(p_pos - scroll_prev_pos);
- Input::get_singleton()->parse_input_event(ev);
- scroll_prev_pos = p_pos;
-}
diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h
index e9c0ec1475..1397ca59e4 100644
--- a/platform/android/android_input_handler.h
+++ b/platform/android/android_input_handler.h
@@ -69,7 +69,6 @@ private:
Vector<TouchPos> touch;
Point2 hover_prev_pos; // needed to calculate the relative position on hover events
- Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events
void _set_key_modifier_state(Ref<InputEventWithModifiers> ev);
@@ -83,7 +82,6 @@ public:
void process_hover(int p_type, Point2 p_pos);
void process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor = 0, float event_horizontal_factor = 0);
void process_double_tap(int event_android_button_mask, Point2 p_pos);
- void process_scroll(Point2 p_pos);
void process_joy_event(JoypadEvent p_event);
void process_key_event(int p_keycode, int p_scancode, int p_unicode_char, bool p_pressed);
};
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 0099ac7e0d..47cfade765 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -1,7 +1,7 @@
import os
import sys
import platform
-from distutils.version import LooseVersion
+import subprocess
def is_active():
@@ -13,41 +13,35 @@ def get_name():
def can_build():
- return ("ANDROID_SDK_ROOT" in os.environ) or ("ANDROID_HOME" in os.environ)
-
-
-def get_platform(platform):
- return int(platform.split("-")[1])
+ return os.path.exists(get_env_android_sdk_root())
def get_opts():
from SCons.Variables import BoolVariable, EnumVariable
return [
- ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()),
- ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()),
+ ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()),
("ndk_platform", 'Target platform (android-<api>, e.g. "android-24")', "android-24"),
EnumVariable("android_arch", "Target architecture", "arm64v8", ("armv7", "arm64v8", "x86", "x86_64")),
]
# Return the ANDROID_SDK_ROOT environment variable.
-# While ANDROID_HOME has been deprecated, it's used as a fallback for backward
-# compatibility purposes.
-def get_android_sdk_root():
- if "ANDROID_SDK_ROOT" in os.environ:
- return os.environ.get("ANDROID_SDK_ROOT", 0)
- else:
- return os.environ.get("ANDROID_HOME", 0)
+def get_env_android_sdk_root():
+ return os.environ.get("ANDROID_SDK_ROOT", -1)
-# Return the ANDROID_NDK_ROOT environment variable.
-# We generate one for this build using the ANDROID_SDK_ROOT env
-# variable and the project ndk version.
-# If the env variable is already defined, we override it with
-# our own to match what the project expects.
-def get_android_ndk_root():
- return get_android_sdk_root() + "/ndk/" + get_project_ndk_version()
+def get_min_sdk_version(platform):
+ return int(platform.split("-")[1])
+
+
+def get_android_ndk_root(env):
+ return env["ANDROID_SDK_ROOT"] + "/ndk/" + get_ndk_version()
+
+
+# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
+def get_ndk_version():
+ return "23.2.8568313"
def get_flags():
@@ -56,133 +50,70 @@ def get_flags():
]
-def create(env):
- tools = env["TOOLS"]
- if "mingw" in tools:
- tools.remove("mingw")
- if "applelink" in tools:
- tools.remove("applelink")
- env.Tool("gcc")
- return env.Clone(tools=tools)
-
-
-# Check if ANDROID_NDK_ROOT is valid.
-# If not, install the ndk using ANDROID_SDK_ROOT and sdkmanager.
+# Check if Android NDK version is installed
+# If not, install it.
def install_ndk_if_needed(env):
print("Checking for Android NDK...")
- env_ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"])
- if env_ndk_version is None:
- # Reinstall the ndk and update ANDROID_NDK_ROOT.
- print("Installing Android NDK...")
- if env["ANDROID_SDK_ROOT"] is None:
- raise Exception("Invalid ANDROID_SDK_ROOT environment variable.")
-
- import subprocess
-
+ sdk_root = env["ANDROID_SDK_ROOT"]
+ if not os.path.exists(get_android_ndk_root(env)):
extension = ".bat" if os.name == "nt" else ""
- sdkmanager_path = env["ANDROID_SDK_ROOT"] + "/cmdline-tools/latest/bin/sdkmanager" + extension
- ndk_download_args = "ndk;" + get_project_ndk_version()
- subprocess.check_call([sdkmanager_path, ndk_download_args])
-
- env["ANDROID_NDK_ROOT"] = env["ANDROID_SDK_ROOT"] + "/ndk/" + get_project_ndk_version()
- print("ANDROID_NDK_ROOT: " + env["ANDROID_NDK_ROOT"])
+ sdkmanager = sdk_root + "/cmdline-tools/latest/bin/sdkmanager" + extension
+ if os.path.exists(sdkmanager):
+ # Install the Android NDK
+ print("Installing Android NDK...")
+ ndk_download_args = "ndk;" + get_ndk_version()
+ subprocess.check_call([sdkmanager, ndk_download_args])
+ else:
+ print("Cannot find " + sdkmanager)
+ print(
+ "Please ensure ANDROID_SDK_ROOT is correct and cmdline-tools are installed, or install NDK version "
+ + get_ndk_version()
+ + " manually."
+ )
+ sys.exit()
+ env["ANDROID_NDK_ROOT"] = get_android_ndk_root(env)
def configure(env):
install_ndk_if_needed(env)
-
- # Workaround for MinGW. See:
- # https://www.scons.org/wiki/LongCmdLinesOnWin32
- if os.name == "nt":
-
- import subprocess
-
- def mySubProcess(cmdline, env):
- # print("SPAWNED : " + cmdline)
- startupinfo = subprocess.STARTUPINFO()
- startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
- proc = subprocess.Popen(
- cmdline,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- startupinfo=startupinfo,
- shell=False,
- env=env,
- )
- data, err = proc.communicate()
- rv = proc.wait()
- if rv:
- print("=====")
- print(err)
- print("=====")
- return rv
-
- def mySpawn(sh, escape, cmd, args, env):
-
- newargs = " ".join(args[1:])
- cmdline = cmd + " " + newargs
-
- rv = 0
- if len(cmdline) > 32000 and cmd.endswith("ar"):
- cmdline = cmd + " " + args[1] + " " + args[2] + " "
- for i in range(3, len(args)):
- rv = mySubProcess(cmdline + args[i], env)
- if rv:
- break
- else:
- rv = mySubProcess(cmdline, env)
-
- return rv
-
- env["SPAWN"] = mySpawn
+ ndk_root = env["ANDROID_NDK_ROOT"]
# Architecture
if env["android_arch"] not in ["armv7", "arm64v8", "x86", "x86_64"]:
- env["android_arch"] = "armv7"
+ env["android_arch"] = "arm64v8"
print("Building for Android, platform " + env["ndk_platform"] + " (" + env["android_arch"] + ")")
- can_vectorize = True
- if env["android_arch"] == "x86":
- env["ARCH"] = "arch-x86"
- env.extra_suffix = ".x86" + env.extra_suffix
- target_subpath = "x86-4.9"
- abi_subpath = "i686-linux-android"
- arch_subpath = "x86"
- env["x86_libtheora_opt_gcc"] = True
- elif env["android_arch"] == "x86_64":
- if get_platform(env["ndk_platform"]) < 21:
+ if get_min_sdk_version(env["ndk_platform"]) < 21:
+ if env["android_arch"] == "x86_64" or env["android_arch"] == "arm64v8":
print(
- "WARNING: android_arch=x86_64 is not supported by ndk_platform lower than android-21; setting"
- " ndk_platform=android-21"
+ "WARNING: android_arch="
+ + env["android_arch"]
+ + " is not supported by ndk_platform lower than android-21; setting ndk_platform=android-21"
)
env["ndk_platform"] = "android-21"
- env["ARCH"] = "arch-x86_64"
- env.extra_suffix = ".x86_64" + env.extra_suffix
- target_subpath = "x86_64-4.9"
- abi_subpath = "x86_64-linux-android"
- arch_subpath = "x86_64"
- env["x86_libtheora_opt_gcc"] = True
- elif env["android_arch"] == "armv7":
- env["ARCH"] = "arch-arm"
- target_subpath = "arm-linux-androideabi-4.9"
- abi_subpath = "arm-linux-androideabi"
- arch_subpath = "armeabi-v7a"
+
+ if env["android_arch"] == "armv7":
+ target_triple = "armv7a-linux-androideabi"
+ bin_utils = "arm-linux-androideabi"
env.extra_suffix = ".armv7" + env.extra_suffix
elif env["android_arch"] == "arm64v8":
- if get_platform(env["ndk_platform"]) < 21:
- print(
- "WARNING: android_arch=arm64v8 is not supported by ndk_platform lower than android-21; setting"
- " ndk_platform=android-21"
- )
- env["ndk_platform"] = "android-21"
- env["ARCH"] = "arch-arm64"
- target_subpath = "aarch64-linux-android-4.9"
- abi_subpath = "aarch64-linux-android"
- arch_subpath = "arm64-v8a"
+ target_triple = "aarch64-linux-android"
+ bin_utils = target_triple
env.extra_suffix = ".armv8" + env.extra_suffix
+ elif env["android_arch"] == "x86":
+ target_triple = "i686-linux-android"
+ bin_utils = target_triple
+ env.extra_suffix = ".x86" + env.extra_suffix
+ elif env["android_arch"] == "x86_64":
+ target_triple = "x86_64-linux-android"
+ bin_utils = target_triple
+ env.extra_suffix = ".x86_64" + env.extra_suffix
+
+ target_option = ["-target", target_triple + str(get_min_sdk_version(env["ndk_platform"]))]
+ env.Append(CCFLAGS=target_option)
+ env.Append(LINKFLAGS=target_option)
# Build type
@@ -191,15 +122,11 @@ def configure(env):
# `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces
# when using `target=release_debug`.
opt = "-O3" if env["target"] == "release" else "-O2"
- env.Append(LINKFLAGS=[opt])
env.Append(CCFLAGS=[opt, "-fomit-frame-pointer"])
elif env["optimize"] == "size": # optimize for size
- env.Append(CCFLAGS=["-Os"])
- env.Append(LINKFLAGS=["-Os"])
-
+ env.Append(CCFLAGS=["-Oz"])
env.Append(CPPDEFINES=["NDEBUG"])
- if can_vectorize:
- env.Append(CCFLAGS=["-ftree-vectorize"])
+ env.Append(CCFLAGS=["-ftree-vectorize"])
elif env["target"] == "debug":
env.Append(LINKFLAGS=["-O0"])
env.Append(CCFLAGS=["-O0", "-g", "-fno-limit-debug-info"])
@@ -211,7 +138,6 @@ def configure(env):
env["SHLIBSUFFIX"] = ".so"
if env["PLATFORM"] == "win32":
- env.Tool("gcc")
env.use_windows_spawn_fix()
if sys.platform.startswith("linux"):
@@ -224,32 +150,15 @@ def configure(env):
else:
host_subpath = "windows"
- compiler_path = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" + host_subpath + "/bin"
- gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath
- tools_path = gcc_toolchain_path + "/" + abi_subpath + "/bin"
-
- # For Clang to find NDK tools in preference of those system-wide
- env.PrependENVPath("PATH", tools_path)
-
- ccache_path = os.environ.get("CCACHE")
- if ccache_path is None:
- env["CC"] = compiler_path + "/clang"
- env["CXX"] = compiler_path + "/clang++"
- else:
- # there aren't any ccache wrappers available for Android,
- # to enable caching we need to prepend the path to the ccache binary
- env["CC"] = ccache_path + " " + compiler_path + "/clang"
- env["CXX"] = ccache_path + " " + compiler_path + "/clang++"
- env["AR"] = tools_path + "/ar"
- env["RANLIB"] = tools_path + "/ranlib"
- env["AS"] = tools_path + "/as"
+ toolchain_path = ndk_root + "/toolchains/llvm/prebuilt/" + host_subpath
+ compiler_path = toolchain_path + "/bin"
+ bin_utils_path = toolchain_path + "/" + bin_utils + "/bin"
- common_opts = ["-gcc-toolchain", gcc_toolchain_path]
-
- # Compile flags
-
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
+ env["CC"] = compiler_path + "/clang"
+ env["CXX"] = compiler_path + "/clang++"
+ env["AR"] = compiler_path + "/llvm-ar"
+ env["RANLIB"] = compiler_path + "/llvm-ranlib"
+ env["AS"] = bin_utils_path + "/as"
# Disable exceptions and rtti on non-tools (template) builds
if env["tools"]:
@@ -261,100 +170,31 @@ def configure(env):
# Don't use dynamic_cast, necessary with no-rtti.
env.Append(CPPDEFINES=["NO_SAFE_CAST"])
- lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env["ndk_platform"] + "/" + env["ARCH"]
-
- # Using NDK unified headers (NDK r15+)
- sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
- env.Append(CPPFLAGS=["--sysroot=" + sysroot])
- env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath])
- env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"])
- # For unified headers this define has to be set manually
- env.Append(CPPDEFINES=[("__ANDROID_API__", str(get_platform(env["ndk_platform"])))])
-
env.Append(
CCFLAGS=(
- "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden"
- " -fno-strict-aliasing".split()
+ "-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing".split()
)
)
env.Append(CPPDEFINES=["NO_STATVFS", "GLES_ENABLED"])
- if get_platform(env["ndk_platform"]) >= 24:
+ if get_min_sdk_version(env["ndk_platform"]) >= 24:
env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
if env["android_arch"] == "x86":
- target_opts = ["-target", "i686-none-linux-android"]
- # The NDK adds this if targeting API < 21, so we can drop it when Godot targets it at least
+ # The NDK adds this if targeting API < 24, so we can drop it when Godot targets it at least
env.Append(CCFLAGS=["-mstackrealign"])
-
- elif env["android_arch"] == "x86_64":
- target_opts = ["-target", "x86_64-none-linux-android"]
-
elif env["android_arch"] == "armv7":
- target_opts = ["-target", "armv7-none-linux-androideabi"]
env.Append(CCFLAGS="-march=armv7-a -mfloat-abi=softfp".split())
env.Append(CPPDEFINES=["__ARM_ARCH_7__", "__ARM_ARCH_7A__"])
- # Enable ARM NEON instructions to compile more optimized code.
- env.Append(CCFLAGS=["-mfpu=neon"])
env.Append(CPPDEFINES=["__ARM_NEON__"])
-
elif env["android_arch"] == "arm64v8":
- target_opts = ["-target", "aarch64-none-linux-android"]
env.Append(CCFLAGS=["-mfix-cortex-a53-835769"])
env.Append(CPPDEFINES=["__ARM_ARCH_8A__"])
- env.Append(CCFLAGS=target_opts)
- env.Append(CCFLAGS=common_opts)
-
# Link flags
- ndk_version = get_env_ndk_version(env["ANDROID_NDK_ROOT"])
- if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
- env.Append(LINKFLAGS=["-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libatomic.a", "-nostdlib++"])
- else:
- env.Append(
- LINKFLAGS=[
- env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libandroid_support.a"
- ]
- )
- env.Append(LINKFLAGS=["-shared", "--sysroot=" + lib_sysroot, "-Wl,--warn-shared-textrel"])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/"])
- env.Append(
- LINKFLAGS=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/" + arch_subpath + "/libc++_shared.so"]
- )
-
- if env["android_arch"] == "armv7":
- env.Append(LINKFLAGS="-Wl,--fix-cortex-a8".split())
- env.Append(LINKFLAGS="-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now".split())
- env.Append(LINKFLAGS="-Wl,-soname,libgodot_android.so -Wl,--gc-sections".split())
-
- env.Append(LINKFLAGS=target_opts)
- env.Append(LINKFLAGS=common_opts)
-
- env.Append(
- LIBPATH=[
- env["ANDROID_NDK_ROOT"]
- + "/toolchains/"
- + target_subpath
- + "/prebuilt/"
- + host_subpath
- + "/lib/gcc/"
- + abi_subpath
- + "/4.9.x"
- ]
- )
- env.Append(
- LIBPATH=[
- env["ANDROID_NDK_ROOT"]
- + "/toolchains/"
- + target_subpath
- + "/prebuilt/"
- + host_subpath
- + "/"
- + abi_subpath
- + "/lib"
- ]
- )
+ env.Append(LINKFLAGS="-Wl,--gc-sections -Wl,--no-undefined -Wl,-z,now".split())
+ env.Append(LINKFLAGS="-Wl,-soname,libgodot_android.so")
env.Prepend(CPPPATH=["#platform/android"])
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED", "NO_FCNTL"])
@@ -364,25 +204,3 @@ def configure(env):
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
if not env["use_volk"]:
env.Append(LIBS=["vulkan"])
-
-
-# Return the project NDK version.
-# This is kept in sync with the value in 'platform/android/java/app/config.gradle'.
-def get_project_ndk_version():
- return "21.4.7075529"
-
-
-# Return NDK version string in source.properties (adapted from the Chromium project).
-def get_env_ndk_version(path):
- if path is None:
- return None
- prop_file_path = os.path.join(path, "source.properties")
- try:
- with open(prop_file_path) as prop_file:
- for line in prop_file:
- key_value = list(map(lambda x: x.strip(), line.split("=")))
- if key_value[0] == "Pkg.Revision":
- return key_value[1]
- except Exception:
- print("Could not read source prop file '%s'" % prop_file_path)
- return None
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index c692f10fd1..b40c1f5090 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -245,7 +245,7 @@ static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
-static const int DEFAULT_TARGET_SDK_VERSION = 30; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
+static const int DEFAULT_TARGET_SDK_VERSION = 31; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION);
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
@@ -1818,7 +1818,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
String can_export_error;
bool can_export_missing_templates;
if (!can_export(p_preset, can_export_error, can_export_missing_templates)) {
- EditorNode::add_io_error(can_export_error);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), can_export_error);
return ERR_UNCONFIGURED;
}
@@ -1897,7 +1897,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
err = OS::get_singleton()->execute(adb, args, &output, &rv, true);
print_verbose(output);
if (err || rv != 0) {
- EditorNode::add_io_error(vformat(TTR("Could not install to device: %s"), output));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Could not install to device: %s"), output));
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
@@ -1975,7 +1975,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
err = OS::get_singleton()->execute(adb, args, &output, &rv, true);
print_verbose(output);
if (err || rv != 0) {
- EditorNode::add_io_error(TTR("Could not execute on device."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), TTR("Could not execute on device."));
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
@@ -2030,7 +2030,7 @@ String EditorExportPlatformAndroid::get_apksigner_path() {
da->list_dir_end();
if (apksigner_path.is_empty()) {
- EditorNode::get_singleton()->show_warning(TTR("Unable to find the 'apksigner' tool."));
+ print_error("Unable to find the 'apksigner' tool.");
}
return apksigner_path;
@@ -2335,7 +2335,7 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
String apksigner = get_apksigner_path();
print_verbose("Starting signing of the " + export_label + " binary using " + apksigner);
if (!FileAccess::exists(apksigner)) {
- EditorNode::add_io_error(vformat(TTR("'apksigner' could not be found.\nPlease check the command is available in the Android SDK build-tools directory.\nThe resulting %s is unsigned."), export_label));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' could not be found. Please check that the command is available in the Android SDK build-tools directory. The resulting %s is unsigned."), export_label));
return OK;
}
@@ -2368,7 +2368,7 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
}
if (!FileAccess::exists(keystore)) {
- EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
}
@@ -2389,10 +2389,14 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
}
int retval;
output.clear();
- OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ Error err = OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start apksigner executable."));
+ return err;
+ }
print_verbose(output);
if (retval) {
- EditorNode::add_io_error(vformat(TTR("'apksigner' returned with error #%d"), retval));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' returned with error #%d"), retval));
return ERR_CANT_CREATE;
}
@@ -2409,10 +2413,14 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
}
output.clear();
- OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ err = OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start apksigner executable."));
+ return err;
+ }
print_verbose(output);
if (retval) {
- EditorNode::add_io_error(vformat(TTR("'apksigner' verification of %s failed."), export_label));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' verification of %s failed."), export_label));
return ERR_CANT_CREATE;
}
@@ -2520,22 +2528,21 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (export_format == EXPORT_FORMAT_AAB) {
if (!p_path.ends_with(".aab")) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid filename! Android App Bundle requires the *.aab extension."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Invalid filename! Android App Bundle requires the *.aab extension."));
return ERR_UNCONFIGURED;
}
if (apk_expansion) {
- EditorNode::get_singleton()->show_warning(TTR("APK Expansion not compatible with Android App Bundle."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("APK Expansion not compatible with Android App Bundle."));
return ERR_UNCONFIGURED;
}
}
if (export_format == EXPORT_FORMAT_APK && !p_path.ends_with(".apk")) {
- EditorNode::get_singleton()->show_warning(
- TTR("Invalid filename! Android APK requires the *.apk extension."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Invalid filename! Android APK requires the *.apk extension."));
return ERR_UNCONFIGURED;
}
if (export_format > EXPORT_FORMAT_AAB || export_format < EXPORT_FORMAT_APK) {
- EditorNode::add_io_error(TTR("Unsupported export format!\n"));
- return ERR_UNCONFIGURED; //TODO: is this the right error?
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unsupported export format!"));
+ return ERR_UNCONFIGURED;
}
if (use_custom_build) {
@@ -2545,13 +2552,13 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("Checking build version..");
Ref<FileAccess> f = FileAccess::open("res://android/.build_version", FileAccess::READ);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
return ERR_UNCONFIGURED;
}
String version = f->get_line().strip_edges();
print_verbose("- build version: " + version);
if (version != VERSION_FULL_CONFIG) {
- EditorNode::get_singleton()->show_warning(vformat(TTR("Android build version mismatch:\n Template installed: %s\n Godot Version: %s\nPlease reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Android build version mismatch: Template installed: %s, Godot version: %s. Please reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
return ERR_UNCONFIGURED;
}
}
@@ -2564,7 +2571,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String project_name = get_project_name(p_preset->get("package/name"));
err = _create_project_name_strings_files(p_preset, project_name); //project name localization.
if (err != OK) {
- EditorNode::add_io_error(TTR("Unable to overwrite res://android/build/res/*.xml files with project name"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res://android/build/res/*.xml files with project name."));
}
// Copies the project icon files into the appropriate Gradle project directory.
_copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background);
@@ -2581,7 +2588,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
user_data.debug = p_debug;
err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
if (err != OK) {
- EditorNode::add_io_error(TTR("Could not export project files to gradle project\n"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not export project files to gradle project."));
return err;
}
if (user_data.libs.size() > 0) {
@@ -2593,7 +2600,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("Saving apk expansion file..");
err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
- EditorNode::add_io_error(TTR("Could not write expansion package file!"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not write expansion package file!"));
return err;
}
}
@@ -2678,7 +2685,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
debug_keystore = OS::get_singleton()->get_resource_dir().plus_file(debug_keystore).simplify_path();
}
if (!FileAccess::exists(debug_keystore)) {
- EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
}
@@ -2694,7 +2701,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
release_keystore = OS::get_singleton()->get_resource_dir().plus_file(release_keystore).simplify_path();
}
if (!FileAccess::exists(release_keystore)) {
- EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
}
@@ -2706,7 +2713,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Building Android Project (gradle)"), build_command, cmdline);
if (result != 0) {
- EditorNode::get_singleton()->show_warning(TTR("Building of Android project failed, check output for the error.\nAlternatively visit docs.godotengine.org for Android build documentation."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Building of Android project failed, check output for the error. Alternatively visit docs.godotengine.org for Android build documentation."));
return ERR_CANT_CREATE;
}
@@ -2736,7 +2743,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("Copying Android binary using gradle command: " + String("\n") + build_command + " " + join_list(copy_args, String(" ")));
int copy_result = EditorNode::get_singleton()->execute_and_show_output(TTR("Moving output"), build_command, copy_args);
if (copy_result != 0) {
- EditorNode::get_singleton()->show_warning(TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
return ERR_CANT_CREATE;
}
@@ -2758,7 +2765,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
src_apk = find_export_template("android_release.apk");
}
if (src_apk.is_empty()) {
- EditorNode::add_io_error(vformat(TTR("Package not found: %s"), src_apk));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Package not found: \"%s\"."), src_apk));
return ERR_FILE_NOT_FOUND;
}
}
@@ -2776,7 +2783,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
unzFile pkg = unzOpen2(src_apk.utf8().get_data(), &io);
if (!pkg) {
- EditorNode::add_io_error(vformat(TTR("Could not find template APK to export:\n%s"), src_apk));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not find template APK to export: \"%s\"."), src_apk));
return ERR_FILE_NOT_FOUND;
}
@@ -2907,7 +2914,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (!invalid_abis.is_empty()) {
String unsupported_arch = String(", ").join(invalid_abis);
- EditorNode::add_io_error(vformat(TTR("Missing libraries in the export template for the selected architectures: %s.\nPlease build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch));
CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
@@ -2925,7 +2932,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (apk_expansion) {
err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
- EditorNode::add_io_error(TTR("Could not write expansion package file!"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not write expansion package file!"));
return err;
}
} else {
@@ -2938,7 +2945,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (err != OK) {
unzClose(pkg);
- EditorNode::add_io_error(TTR("Could not export project files"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not export project files.")));
CLEANUP_AND_RETURN(ERR_SKIP);
}
@@ -2974,7 +2981,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
unzFile tmp_unaligned = unzOpen2(tmp_unaligned_path.utf8().get_data(), &io);
if (!tmp_unaligned) {
- EditorNode::add_io_error(TTR("Could not unzip temporary unaligned APK."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not unzip temporary unaligned APK.")));
CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index c98e8f1d55..2d4c4763a2 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -59,6 +59,7 @@
android:theme="@style/GodotAppSplashTheme"
android:launchMode="singleTask"
android:excludeFromRecents="false"
+ android:exported="true"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:resizeableActivity="false"
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index b6303d1bc9..63b10e62b1 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -1,6 +1,4 @@
// Gradle build config for Godot Engine's Android port.
-apply from: 'config.gradle'
-
buildscript {
apply from: 'config.gradle'
@@ -14,7 +12,12 @@ buildscript {
}
}
-apply plugin: 'com.android.application'
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+apply from: 'config.gradle'
allprojects {
repositories {
@@ -79,6 +82,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
assetPacks = [":assetPacks:installTime"]
defaultConfig {
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 1b2976e715..3daf628e63 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,20 +1,21 @@
ext.versions = [
androidGradlePlugin: '7.0.3',
- compileSdk : 30,
+ compileSdk : 31,
minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
- targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
+ targetSdk : 31, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
buildTools : '30.0.3',
- kotlinVersion : '1.6.10',
+ kotlinVersion : '1.6.21',
fragmentVersion : '1.3.6',
+ nexusPublishVersion: '1.1.0',
javaVersion : 11,
- ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
+ ndkVersion : '23.2.8568313' // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated.
]
ext.libraries = [
androidGradlePlugin: "com.android.tools.build:gradle:$versions.androidGradlePlugin",
kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlinVersion",
- kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlinVersion",
+ kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlinVersion",
androidxFragment : "androidx.fragment:fragment:$versions.fragmentVersion",
]
diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle
index e38d7b2ba6..ba53aefe7f 100644
--- a/platform/android/java/app/settings.gradle
+++ b/platform/android/java/app/settings.gradle
@@ -1,2 +1,15 @@
// This is the root directory of the Godot custom build.
+pluginManagement {
+ apply from: 'config.gradle'
+
+ plugins {
+ id 'com.android.application' version versions.androidGradlePlugin
+ id 'org.jetbrains.kotlin.android' version versions.kotlinVersion
+ }
+ repositories {
+ gradlePluginPortal()
+ google()
+ }
+}
+
include ':assetPacks:installTime'
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index e16ca65df5..da30bd3a95 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -1,7 +1,3 @@
-apply plugin: 'io.github.gradle-nexus.publish-plugin'
-apply from: 'app/config.gradle'
-apply from: 'scripts/publish-root.gradle'
-
buildscript {
apply from: 'app/config.gradle'
@@ -17,6 +13,13 @@ buildscript {
}
}
+plugins {
+ id 'io.github.gradle-nexus.publish-plugin'
+}
+
+apply from: 'app/config.gradle'
+apply from: 'scripts/publish-root.gradle'
+
allprojects {
repositories {
google()
diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle
index 3312f61ad3..dd167c3880 100644
--- a/platform/android/java/editor/build.gradle
+++ b/platform/android/java/editor/build.gradle
@@ -1,10 +1,15 @@
// Gradle build config for Godot Engine's Android port.
-apply plugin: 'com.android.application'
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
implementation project(":lib")
+
+ implementation "androidx.window:window:1.0.0"
}
android {
@@ -29,6 +34,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
buildTypes {
dev {
initWith debug
diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml
index bae075d929..93cbb47400 100644
--- a/platform/android/java/editor/src/main/AndroidManifest.xml
+++ b/platform/android/java/editor/src/main/AndroidManifest.xml
@@ -34,6 +34,9 @@
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:process=":GodotProjectManager">
+ <layout android:defaultHeight="@dimen/editor_default_window_height"
+ android:defaultWidth="@dimen/editor_default_window_width" />
+
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -46,7 +49,10 @@
android:process=":GodotEditor"
android:launchMode="singleTask"
android:screenOrientation="userLandscape"
+ android:exported="false"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
+ <layout android:defaultHeight="@dimen/editor_default_window_height"
+ android:defaultWidth="@dimen/editor_default_window_width" />
</activity>
<activity
@@ -55,8 +61,11 @@
android:label="@string/godot_project_name_string"
android:process=":GodotGame"
android:launchMode="singleTask"
+ android:exported="false"
android:screenOrientation="userLandscape"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
+ <layout android:defaultHeight="@dimen/editor_default_window_height"
+ android:defaultWidth="@dimen/editor_default_window_width" />
</activity>
</application>
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java
deleted file mode 100644
index 8a6bf88267..0000000000
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************/
-/* GodotEditor.java */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-package org.godotengine.editor;
-
-import org.godotengine.godot.FullScreenGodotApp;
-import org.godotengine.godot.utils.PermissionsUtil;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Debug;
-
-import androidx.annotation.Nullable;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Base class for the Godot Android Editor activities.
- *
- * This provides the basic templates for the activities making up this application.
- * Each derived activity runs in its own process, which enable up to have several instances of
- * the Godot engine up and running at the same time.
- *
- * It also plays the role of the primary editor window.
- */
-public class GodotEditor extends FullScreenGodotApp {
- private static final boolean WAIT_FOR_DEBUGGER = false;
- private static final String COMMAND_LINE_PARAMS = "command_line_params";
-
- private static final String EDITOR_ARG = "--editor";
- private static final String PROJECT_MANAGER_ARG = "--project-manager";
-
- private final List<String> commandLineParams = new ArrayList<>();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- PermissionsUtil.requestManifestPermissions(this);
-
- String[] params = getIntent().getStringArrayExtra(COMMAND_LINE_PARAMS);
- updateCommandLineParams(params);
-
- if (BuildConfig.BUILD_TYPE.equals("debug") && WAIT_FOR_DEBUGGER) {
- Debug.waitForDebugger();
- }
- super.onCreate(savedInstanceState);
- }
-
- private void updateCommandLineParams(@Nullable String[] args) {
- // Update the list of command line params with the new args
- commandLineParams.clear();
- if (args != null && args.length > 0) {
- commandLineParams.addAll(Arrays.asList(args));
- }
- }
-
- @Override
- public List<String> getCommandLine() {
- return commandLineParams;
- }
-
- @Override
- public void onNewGodotInstanceRequested(String[] args) {
- // Parse the arguments to figure out which activity to start.
- Class<?> targetClass = GodotGame.class;
- for (String arg : args) {
- if (EDITOR_ARG.equals(arg)) {
- targetClass = GodotEditor.class;
- break;
- }
-
- if (PROJECT_MANAGER_ARG.equals(arg)) {
- targetClass = GodotProjectManager.class;
- break;
- }
- }
-
- // Launch a new activity
- Intent newInstance = new Intent(this, targetClass).putExtra(COMMAND_LINE_PARAMS, args);
- startActivity(newInstance);
- }
-
- @Override
- public void setRequestedOrientation(int requestedOrientation) {
- if (!overrideOrientationRequest()) {
- super.setRequestedOrientation(requestedOrientation);
- }
- }
-
- /**
- * The Godot Android Editor sets its own orientation via its AndroidManifest
- */
- protected boolean overrideOrientationRequest() {
- return true;
- }
-}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
new file mode 100644
index 0000000000..a1ade722e8
--- /dev/null
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
@@ -0,0 +1,146 @@
+/*************************************************************************/
+/* GodotEditor.kt */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.editor
+
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.os.Debug
+import androidx.window.layout.WindowMetricsCalculator
+import org.godotengine.godot.FullScreenGodotApp
+import org.godotengine.godot.utils.PermissionsUtil
+import java.util.*
+import kotlin.math.min
+
+/**
+ * Base class for the Godot Android Editor activities.
+ *
+ * This provides the basic templates for the activities making up this application.
+ * Each derived activity runs in its own process, which enable up to have several instances of
+ * the Godot engine up and running at the same time.
+ *
+ * It also plays the role of the primary editor window.
+ */
+open class GodotEditor : FullScreenGodotApp() {
+
+ companion object {
+ private const val WAIT_FOR_DEBUGGER = false
+
+ private const val COMMAND_LINE_PARAMS = "command_line_params"
+
+ private const val EDITOR_ARG = "--editor"
+ private const val PROJECT_MANAGER_ARG = "--project-manager"
+ }
+
+ private val commandLineParams = ArrayList<String>()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ PermissionsUtil.requestManifestPermissions(this)
+
+ val params = intent.getStringArrayExtra(COMMAND_LINE_PARAMS)
+ updateCommandLineParams(params)
+
+ if (BuildConfig.BUILD_TYPE == "debug" && WAIT_FOR_DEBUGGER) {
+ Debug.waitForDebugger()
+ }
+
+ super.onCreate(savedInstanceState)
+ }
+
+ private fun updateCommandLineParams(args: Array<String>?) {
+ // Update the list of command line params with the new args
+ commandLineParams.clear()
+ if (args != null && args.isNotEmpty()) {
+ commandLineParams.addAll(listOf(*args))
+ }
+ }
+
+ override fun getCommandLine() = commandLineParams
+
+ override fun onNewGodotInstanceRequested(args: Array<String>) {
+ // Parse the arguments to figure out which activity to start.
+ var targetClass: Class<*> = GodotGame::class.java
+
+ // Whether we should launch the new godot instance in an adjacent window
+ // https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
+ var launchAdjacent =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen)
+
+ for (arg in args) {
+ if (EDITOR_ARG == arg) {
+ targetClass = GodotEditor::class.java
+ launchAdjacent = false
+ break
+ }
+
+ if (PROJECT_MANAGER_ARG == arg) {
+ targetClass = GodotProjectManager::class.java
+ launchAdjacent = false
+ break
+ }
+ }
+
+ // Launch a new activity
+ val newInstance = Intent(this, targetClass)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(COMMAND_LINE_PARAMS, args)
+ if (launchAdjacent) {
+ newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT)
+ }
+ startActivity(newInstance)
+ }
+
+ // Get the screen's density scale
+ protected val isLargeScreen: Boolean
+ // Get the minimum window size // Correspond to the EXPANDED window size class.
+ get() {
+ val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
+
+ // Get the screen's density scale
+ val scale = resources.displayMetrics.density
+
+ // Get the minimum window size
+ val minSize = min(metrics.bounds.width(), metrics.bounds.height()).toFloat()
+ val minSizeDp = minSize / scale
+ return minSizeDp >= 840f // Correspond to the EXPANDED window size class.
+ }
+
+ override fun setRequestedOrientation(requestedOrientation: Int) {
+ if (!overrideOrientationRequest()) {
+ super.setRequestedOrientation(requestedOrientation)
+ }
+ }
+
+ /**
+ * The Godot Android Editor sets its own orientation via its AndroidManifest
+ */
+ protected open fun overrideOrientationRequest() = true
+}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt
index 12766775a8..783095f93a 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotGame.java */
+/* GodotGame.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+package org.godotengine.editor
/**
* Drives the 'run project' window of the Godot Editor.
*/
-public class GodotGame extends GodotEditor {
- protected boolean overrideOrientationRequest() {
- return false;
- }
+class GodotGame : GodotEditor() {
+ override fun overrideOrientationRequest() = false
}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt
index d30f66bb8c..bcf4659603 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotProjectManager.java */
+/* GodotProjectManager.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,14 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+package org.godotengine.editor
/**
* Launcher activity for the Godot Android Editor.
*
* It presents the user with the project manager interface.
* Upon selection of a project, this activity (via its parent logic) starts the
- * {@link GodotEditor} activity.
+ * [GodotEditor] activity.
*/
-public class GodotProjectManager extends GodotEditor {
-}
+class GodotProjectManager : GodotEditor()
diff --git a/platform/android/java/editor/src/main/res/values/dimens.xml b/platform/android/java/editor/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..03fb6184d2
--- /dev/null
+++ b/platform/android/java/editor/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="editor_default_window_height">600dp</dimen>
+ <dimen name="editor_default_window_width">800dp</dimen>
+</resources>
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 90dc61a6ac..228d8d45fa 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionName="1.0">
<!-- Should match the mindSdk and targetSdk values in platform/android/java/app/config.gradle -->
- <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<application>
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index c806de1ded..6b82326a27 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -1,5 +1,7 @@
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
+plugins {
+ id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
+}
ext {
PUBLISH_VERSION = getGodotPublishVersion()
@@ -34,6 +36,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
buildTypes {
dev {
initWith debug
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index b69d25dd8b..a8e3669ac6 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -224,12 +224,30 @@ public class GodotIO {
}
public int getScreenDPI() {
- DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
- return (int)(metrics.density * 160f);
+ return activity.getResources().getDisplayMetrics().densityDpi;
}
+ /**
+ * Returns bucketized density values.
+ */
public float getScaledDensity() {
- return activity.getResources().getDisplayMetrics().scaledDensity;
+ int densityDpi = activity.getResources().getDisplayMetrics().densityDpi;
+ float selectedScaledDensity;
+ if (densityDpi >= DisplayMetrics.DENSITY_XXXHIGH) {
+ selectedScaledDensity = 4.0f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_XXHIGH) {
+ selectedScaledDensity = 3.0f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_XHIGH) {
+ selectedScaledDensity = 2.0f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_HIGH) {
+ selectedScaledDensity = 1.5f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_MEDIUM) {
+ selectedScaledDensity = 1.0f;
+ } else {
+ selectedScaledDensity = 0.75f;
+ }
+ Log.d(TAG, "Selected scaled density: " + selectedScaledDensity);
+ return selectedScaledDensity;
}
public double getScreenRefreshRate(double fallback) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 1f8f8c82a6..3182ab0666 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -114,11 +114,6 @@ public class GodotLib {
public static native void doubleTap(int buttonMask, int x, int y);
/**
- * Forward scroll events from the main thread to the GL thread.
- */
- public static native void scroll(int x, int y);
-
- /**
* Forward accelerometer sensor events from the main thread to the GL thread.
* @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent)
*/
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index ac13cad23e..778efa914a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -80,15 +80,6 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener
}
@Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- //Log.i("GodotGesture", "onScroll");
- final int x = Math.round(distanceX);
- final int y = Math.round(distanceY);
- GodotLib.scroll(x, y);
- return true;
- }
-
- @Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
//Log.i("GodotGesture", "onFling");
return true;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index 8694bb91e1..ccfb865b1a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -186,6 +186,9 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
if (mJoystickIds.indexOfKey(deviceId) >= 0) {
final int godotJoyId = mJoystickIds.get(deviceId);
Joystick joystick = mJoysticksDevices.get(deviceId);
+ if (joystick == null) {
+ return true;
+ }
for (int i = 0; i < joystick.axes.size(); i++) {
final int axis = joystick.axes.get(i);
diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle
index 0cb769b539..5e810ae1ba 100644
--- a/platform/android/java/nativeSrcsConfigs/build.gradle
+++ b/platform/android/java/nativeSrcsConfigs/build.gradle
@@ -1,6 +1,7 @@
// Non functional android library used to provide Android Studio editor support to the project.
plugins {
id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
}
android {
@@ -18,6 +19,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle
index 56e1b6fd3a..466ffebf22 100644
--- a/platform/android/java/settings.gradle
+++ b/platform/android/java/settings.gradle
@@ -1,4 +1,19 @@
// Configure the root project.
+pluginManagement {
+ apply from: 'app/config.gradle'
+
+ plugins {
+ id 'com.android.application' version versions.androidGradlePlugin
+ id 'com.android.library' version versions.androidGradlePlugin
+ id 'org.jetbrains.kotlin.android' version versions.kotlinVersion
+ id 'io.github.gradle-nexus.publish-plugin' version versions.nexusPublishVersion
+ }
+ repositories {
+ gradlePluginPortal()
+ google()
+ }
+}
+
rootProject.name = "Godot"
include ':app'
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index de666f1b11..eaffe14b13 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -306,15 +306,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env
}
// Called on the UI thread
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y) {
- if (step.get() <= 0) {
- return;
- }
-
- input_handler->process_scroll(Point2(p_x, p_y));
-}
-
-// Called on the UI thread
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed) {
if (step.get() <= 0) {
return;
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index e1d30eea77..aa8d67cf46 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -51,7 +51,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FI(JNIEn
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch__IIII_3FIFF(JNIEnv *env, jclass clazz, jint input_device, jint ev, jint pointer, jint pointer_count, jfloatArray positions, jint buttons_mask, jfloat vertical_factor, jfloat horizontal_factor);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jclass clazz, jint p_type, jfloat p_x, jfloat p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubleTap(JNIEnv *env, jclass clazz, jint p_button_mask, jint p_x, jint p_y);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jclass clazz, jint p_x, jint p_y);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jclass clazz, jint p_keycode, jint p_scancode, jint p_unicode_char, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jclass clazz, jint p_device, jint p_button, jboolean p_pressed);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jclass clazz, jint p_device, jint p_axis, jfloat p_value);