From a5897d579bb0af496a18f7430345a67fe27ff0df Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Sun, 16 Jun 2024 12:14:34 -0700 Subject: Update the `GodotHost` interface to support signing and verifying Android apks Update the export logic to enable apk generation and signing for Android editor builds Note: Only legacy builds are supported. Gradle builds are not supported at this point in time. --- .../java/lib/src/org/godotengine/godot/Godot.kt | 18 +++++++++++++- .../src/org/godotengine/godot/GodotFragment.java | 17 +++++++++++++ .../lib/src/org/godotengine/godot/GodotHost.java | 28 ++++++++++++++++++++++ .../src/org/godotengine/godot/io/StorageScope.kt | 8 +++++++ .../godotengine/godot/io/file/FileAccessHandler.kt | 2 +- 5 files changed, 71 insertions(+), 2 deletions(-) (limited to 'platform/android/java/lib/src/org') diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt index 1e0027089c..49e8ffb008 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -50,6 +50,7 @@ import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsAnimationCompat import androidx.core.view.WindowInsetsCompat import com.google.android.vending.expansion.downloader.* +import org.godotengine.godot.error.Error import org.godotengine.godot.input.GodotEditText import org.godotengine.godot.input.GodotInputHandler import org.godotengine.godot.io.directory.DirectoryAccessHandler @@ -96,7 +97,6 @@ class Godot(private val context: Context) { fun isEditorBuild() = BuildConfig.FLAVOR == EDITOR_FLAVOR } - private val windowManager: WindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager private val mSensorManager: SensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager private val mClipboard: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager private val vibratorService: Vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator @@ -1054,4 +1054,20 @@ class Godot(private val context: Context) { private fun nativeDumpBenchmark(benchmarkFile: String) { dumpBenchmark(fileAccessHandler, benchmarkFile) } + + @Keep + private fun nativeSignApk(inputPath: String, + outputPath: String, + keystorePath: String, + keystoreUser: String, + keystorePassword: String): Int { + val signResult = primaryHost?.signApk(inputPath, outputPath, keystorePath, keystoreUser, keystorePassword) ?: Error.ERR_UNAVAILABLE + return signResult.toNativeValue() + } + + @Keep + private fun nativeVerifyApk(apkPath: String): Int { + val verifyResult = primaryHost?.verifyApk(apkPath) ?: Error.ERR_UNAVAILABLE + return verifyResult.toNativeValue() + } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java b/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java index fdda766594..e0f5744368 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotFragment.java @@ -30,6 +30,7 @@ package org.godotengine.godot; +import org.godotengine.godot.error.Error; import org.godotengine.godot.plugin.GodotPlugin; import org.godotengine.godot.utils.BenchmarkUtils; @@ -484,4 +485,20 @@ public class GodotFragment extends Fragment implements IDownloaderClient, GodotH } return Collections.emptySet(); } + + @Override + public Error signApk(@NonNull String inputPath, @NonNull String outputPath, @NonNull String keystorePath, @NonNull String keystoreUser, @NonNull String keystorePassword) { + if (parentHost != null) { + return parentHost.signApk(inputPath, outputPath, keystorePath, keystoreUser, keystorePassword); + } + return Error.ERR_UNAVAILABLE; + } + + @Override + public Error verifyApk(@NonNull String apkPath) { + if (parentHost != null) { + return parentHost.verifyApk(apkPath); + } + return Error.ERR_UNAVAILABLE; + } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java index 1862b9fa9b..f1c84e90a7 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java @@ -30,10 +30,13 @@ package org.godotengine.godot; +import org.godotengine.godot.error.Error; import org.godotengine.godot.plugin.GodotPlugin; import android.app.Activity; +import androidx.annotation.NonNull; + import java.util.Collections; import java.util.List; import java.util.Set; @@ -108,4 +111,29 @@ public interface GodotHost { default Set getHostPlugins(Godot engine) { return Collections.emptySet(); } + + /** + * Signs the given Android apk + * + * @param inputPath Path to the apk that should be signed + * @param outputPath Path for the signed output apk; can be the same as inputPath + * @param keystorePath Path to the keystore to use for signing the apk + * @param keystoreUser Keystore user credential + * @param keystorePassword Keystore password credential + * + * @return {@link Error#OK} if signing is successful + */ + default Error signApk(@NonNull String inputPath, @NonNull String outputPath, @NonNull String keystorePath, @NonNull String keystoreUser, @NonNull String keystorePassword) { + return Error.ERR_UNAVAILABLE; + } + + /** + * Verifies the given Android apk is signed + * + * @param apkPath Path to the apk that should be verified + * @return {@link Error#OK} if verification was successful + */ + default Error verifyApk(@NonNull String apkPath) { + return Error.ERR_UNAVAILABLE; + } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt index 2e5649b563..574ecd58eb 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt @@ -73,6 +73,14 @@ internal enum class StorageScope { private val downloadsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath private val documentsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath + /** + * Determine if the given path is accessible. + */ + fun canAccess(path: String?): Boolean { + val storageScope = identifyStorageScope(path) + return storageScope == APP || storageScope == SHARED + } + /** * Determines which [StorageScope] the given path falls under. */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt index 5d57052ce6..5d87f23b4a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/FileAccessHandler.kt @@ -107,7 +107,7 @@ class FileAccessHandler(val context: Context) { } } - private val storageScopeIdentifier = StorageScope.Identifier(context) + internal val storageScopeIdentifier = StorageScope.Identifier(context) private val files = SparseArray() private var lastFileId = STARTING_FILE_ID -- cgit v1.2.3