You've already forked godot
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:
committed by
Fredia Huya-Kouadio
parent
0c7a15d777
commit
5711037bf6
@@ -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()
|
||||
// }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user