1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-11 13:10:58 +00:00

Android port of the Godot Editor

These set of changes focus primarily on getting the core logic and overall Godot Editor UI and functionality up and running natively on Android devices.
UI tweaks / cleanup / polish, as well configuration for Android specific functionality / restrictions will be addressed in follow-up PRs iteratively based on feedback.

Co-authored-by: thebestnom <shoval.arad@gmail.com>
This commit is contained in:
Fredy Huya-Kouadio
2021-06-25 16:45:16 +03:00
committed by Fredia Huya-Kouadio
parent 0c7a15d777
commit 5711037bf6
25 changed files with 744 additions and 72 deletions

View File

@@ -18,14 +18,13 @@ def pathToRootDir = "../../../../"
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
ndkVersion versions.ndkVersion
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersion()]
manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersionName()]
}
namespace = "org.godotengine.godot"
@@ -35,6 +34,18 @@ android {
targetCompatibility versions.javaVersion
}
buildTypes {
dev {
initWith debug
}
}
flavorDimensions "products"
productFlavors {
editor {}
template {}
}
lintOptions {
abortOnError false
disable 'MissingTranslation', 'UnusedResources'
@@ -58,24 +69,50 @@ android {
aidl.srcDirs = ['aidl']
assets.srcDirs = ['assets']
}
debug.jniLibs.srcDirs = ['libs/debug']
dev.jniLibs.srcDirs = ['libs/dev']
release.jniLibs.srcDirs = ['libs/release']
// Editor jni library
editorDebug.jniLibs.srcDirs = ['libs/tools/debug']
editorDev.jniLibs.srcDirs = ['libs/tools/dev']
}
// Disable 'editorRelease'.
// The editor can't be used with target=release as debugging tools are then not
// included, and it would crash on errors instead of reporting them.
variantFilter { variant ->
if (variant.name == "editorRelease") {
setIgnore(true)
}
}
libraryVariants.all { variant ->
def flavorName = variant.getFlavorName()
if (flavorName == null || flavorName == "") {
throw new GradleException("Invalid product flavor: $flavorName")
}
boolean toolsFlag = flavorName == "editor"
def buildType = variant.buildType.name
if (buildType == null || buildType == "" || !supportedTargetsMap.containsKey(buildType)) {
throw new GradleException("Invalid build type: $buildType")
}
def sconsTarget = supportedTargetsMap[buildType]
if (sconsTarget == null || sconsTarget == "") {
throw new GradleException("Invalid scons target: $sconsTarget")
}
// Update the name of the generated library
def outputSuffix = "${buildType}.aar"
if (toolsFlag) {
outputSuffix = "tools.$outputSuffix"
}
variant.outputs.all { output ->
output.outputFileName = "godot-lib.${variant.name}.aar"
}
def buildType = variant.buildType.name.capitalize()
def releaseTarget = buildType.toLowerCase()
if (releaseTarget == null || releaseTarget == "") {
throw new GradleException("Invalid build type: " + buildType)
}
if (!supportedAbis.contains(defaultAbi)) {
throw new GradleException("Invalid default abi: " + defaultAbi)
output.outputFileName = "godot-lib.${outputSuffix}"
}
// Find scons' executable path
@@ -88,13 +125,11 @@ android {
for (ext in sconsExts) {
String sconsNameExt = sconsName + ext
logger.lifecycle("Checking $sconsNameExt")
sconsExecutableFile = org.gradle.internal.os.OperatingSystem.current().findInPath(sconsNameExt)
if (sconsExecutableFile != null) {
// We're done!
break
}
// Check all the options in path
List<File> allOptions = org.gradle.internal.os.OperatingSystem.current().findAllInPath(sconsNameExt)
if (!allOptions.isEmpty()) {
@@ -103,27 +138,32 @@ android {
break
}
}
if (sconsExecutableFile == null) {
throw new GradleException("Unable to find executable path for the '$sconsName' command.")
} else {
logger.lifecycle("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}")
}
// Creating gradle task to generate the native libraries for the default abi.
def taskName = getSconsTaskName(buildType)
tasks.create(name: taskName, type: Exec) {
executable sconsExecutableFile.absolutePath
args "--directory=${pathToRootDir}", "platform=android", "target=${releaseTarget}", "android_arch=${defaultAbi}", "-j" + Runtime.runtime.availableProcessors()
}
for (String selectedAbi : selectedAbis) {
if (!supportedAbis.contains(selectedAbi)) {
throw new GradleException("Invalid selected abi: $selectedAbi")
}
// Schedule the tasks so the generated libs are present before the aar file is packaged.
tasks["merge${buildType}JniLibFolders"].dependsOn taskName
// Creating gradle task to generate the native libraries for the selected abi.
def taskName = getSconsTaskName(flavorName, buildType, selectedAbi)
tasks.create(name: taskName, type: Exec) {
executable sconsExecutableFile.absolutePath
args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "android_arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
}
// Schedule the tasks so the generated libs are present before the aar file is packaged.
tasks["merge${flavorName.capitalize()}${buildType.capitalize()}JniLibFolders"].dependsOn taskName
}
}
// TODO: Enable when issues with AGP 7.1+ are resolved (https://github.com/GodotVR/godot_openxr/issues/187).
// publishing {
// singleVariant("release") {
// singleVariant("templateRelease") {
// withSourcesJar()
// withJavadocJar()
// }

View File

@@ -47,7 +47,6 @@ import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -333,9 +332,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public void restart() {
if (godotHost != null) {
godotHost.onGodotRestartRequested(this);
}
runOnUiThread(() -> {
if (godotHost != null) {
godotHost.onGodotRestartRequested(this);
}
});
}
public void alert(final String message, final String title) {
@@ -859,9 +860,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private void forceQuit() {
// TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
// native Godot components that is started in Godot#onVideoInit.
if (godotHost != null) {
godotHost.onGodotForceQuit(this);
}
runOnUiThread(() -> {
if (godotHost != null) {
godotHost.onGodotForceQuit(this);
}
});
}
private boolean obbIsCorrupted(String f, String main_pack_md5) {
@@ -1010,6 +1013,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
mProgressFraction.setText(Helpers.getDownloadProgressString(progress.mOverallProgress,
progress.mOverallTotal));
}
public void initInputDevices() {
mRenderView.initInputDevices();
}
@@ -1018,4 +1022,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private GodotRenderView getRenderView() { // used by native side to get renderView
return mRenderView;
}
@Keep
private void createNewGodotInstance(String[] args) {
runOnUiThread(() -> {
if (godotHost != null) {
godotHost.onNewGodotInstanceRequested(args);
}
});
}
}

View File

@@ -60,8 +60,16 @@ public interface GodotHost {
default void onGodotForceQuit(Godot instance) {}
/**
* Invoked on the GL thread when the Godot instance wants to be restarted. It's up to the host
* Invoked on the UI thread when the Godot instance wants to be restarted. It's up to the host
* to perform the appropriate action(s).
*/
default void onGodotRestartRequested(Godot instance) {}
/**
* Invoked on the UI thread when a new Godot instance is requested. It's up to the host to
* perform the appropriate action(s).
*
* @param args Arguments used to initialize the new instance.
*/
default void onNewGodotInstanceRequested(String[] args) {}
}