diff options
Diffstat (limited to 'platform/android/java/lib')
7 files changed, 80 insertions, 42 deletions
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 0434efdf4c..d283de8ce8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -203,9 +203,10 @@ public class GodotIO { return result; } - public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { - if (edit != null) - edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); + public void showKeyboard(String p_existing_text, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { + if (edit != null) { + edit.showKeyboard(p_existing_text, GodotEditText.VirtualKeyboardType.values()[p_type], p_max_input_length, p_cursor_start, p_cursor_end); + } //InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); //inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index ecb2af0a7b..7925b54fc4 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -52,6 +52,18 @@ public class GodotEditText extends EditText { private final static int HANDLER_OPEN_IME_KEYBOARD = 2; private final static int HANDLER_CLOSE_IME_KEYBOARD = 3; + // Enum must be kept up-to-date with DisplayServer::VirtualKeyboardType + public enum VirtualKeyboardType { + KEYBOARD_TYPE_DEFAULT, + KEYBOARD_TYPE_MULTILINE, + KEYBOARD_TYPE_NUMBER, + KEYBOARD_TYPE_NUMBER_DECIMAL, + KEYBOARD_TYPE_PHONE, + KEYBOARD_TYPE_EMAIL_ADDRESS, + KEYBOARD_TYPE_PASSWORD, + KEYBOARD_TYPE_URL + } + // =========================================================== // Fields // =========================================================== @@ -60,7 +72,7 @@ public class GodotEditText extends EditText { private EditHandler sHandler = new EditHandler(this); private String mOriginText; private int mMaxInputLength = Integer.MAX_VALUE; - private boolean mMultiline = false; + private VirtualKeyboardType mKeyboardType = VirtualKeyboardType.KEYBOARD_TYPE_DEFAULT; private static class EditHandler extends Handler { private final WeakReference<GodotEditText> mEdit; @@ -100,8 +112,8 @@ public class GodotEditText extends EditText { setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE); } - public boolean isMultiline() { - return mMultiline; + public VirtualKeyboardType getKeyboardType() { + return mKeyboardType; } private void handleMessage(final Message msg) { @@ -122,8 +134,31 @@ public class GodotEditText extends EditText { } int inputType = InputType.TYPE_CLASS_TEXT; - if (edit.isMultiline()) { - inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE; + switch (edit.getKeyboardType()) { + case KEYBOARD_TYPE_DEFAULT: + inputType = InputType.TYPE_CLASS_TEXT; + break; + case KEYBOARD_TYPE_MULTILINE: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE; + break; + case KEYBOARD_TYPE_NUMBER: + inputType = InputType.TYPE_CLASS_NUMBER; + break; + case KEYBOARD_TYPE_NUMBER_DECIMAL: + inputType = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + break; + case KEYBOARD_TYPE_PHONE: + inputType = InputType.TYPE_CLASS_PHONE; + break; + case KEYBOARD_TYPE_EMAIL_ADDRESS: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; + break; + case KEYBOARD_TYPE_PASSWORD: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD; + break; + case KEYBOARD_TYPE_URL: + inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI; + break; } edit.setInputType(inputType); @@ -201,7 +236,7 @@ public class GodotEditText extends EditText { // =========================================================== // Methods // =========================================================== - public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { + public void showKeyboard(String p_existing_text, VirtualKeyboardType p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length; if (p_cursor_start == -1) { // cursor position not given this.mOriginText = p_existing_text; @@ -214,7 +249,7 @@ public class GodotEditText extends EditText { this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end); } - this.mMultiline = p_multiline; + this.mKeyboardType = p_type; final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index e940aafa9e..7714703a21 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -115,7 +115,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } for (int i = 0; i < count; ++i) { int key = newChars[i]; - if ((key == '\n') && !mEdit.isMultiline()) { + if ((key == '\n') && !(mEdit.getKeyboardType() == GodotEditText.VirtualKeyboardType.KEYBOARD_TYPE_MULTILINE)) { // Return keys are handled through action events continue; } 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 c7bd55b620..c9282dd247 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 @@ -54,11 +54,19 @@ internal enum class StorageScope { */ UNKNOWN; - companion object { + class Identifier(context: Context) { + + private val internalAppDir: String? = context.filesDir.canonicalPath + private val internalCacheDir: String? = context.cacheDir.canonicalPath + private val externalAppDir: String? = context.getExternalFilesDir(null)?.canonicalPath + private val sharedDir : String? = Environment.getExternalStorageDirectory().canonicalPath + private val downloadsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath + private val documentsSharedDir: String? = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath + /** * Determines which [StorageScope] the given path falls under. */ - fun getStorageScope(context: Context, path: String?): StorageScope { + fun identifyStorageScope(path: String?): StorageScope { if (path == null) { return UNKNOWN } @@ -70,23 +78,19 @@ internal enum class StorageScope { val canonicalPathFile = pathFile.canonicalPath - val internalAppDir = context.filesDir.canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(internalAppDir)) { + if (internalAppDir != null && canonicalPathFile.startsWith(internalAppDir)) { return APP } - val internalCacheDir = context.cacheDir.canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(internalCacheDir)) { + if (internalCacheDir != null && canonicalPathFile.startsWith(internalCacheDir)) { return APP } - val externalAppDir = context.getExternalFilesDir(null)?.canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(externalAppDir)) { + if (externalAppDir != null && canonicalPathFile.startsWith(externalAppDir)) { return APP } - val sharedDir = Environment.getExternalStorageDirectory().canonicalPath ?: return UNKNOWN - if (canonicalPathFile.startsWith(sharedDir)) { + if (sharedDir != null && canonicalPathFile.startsWith(sharedDir)) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { // Before R, apps had access to shared storage so long as they have the right // permissions (and flag on Q). @@ -95,13 +99,8 @@ internal enum class StorageScope { // Post R, access is limited based on the target destination // 'Downloads' and 'Documents' are still accessible - val downloadsSharedDir = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).canonicalPath - ?: return SHARED - val documentsSharedDir = - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).canonicalPath - ?: return SHARED - if (canonicalPathFile.startsWith(downloadsSharedDir) || canonicalPathFile.startsWith(documentsSharedDir)) { + if ((downloadsSharedDir != null && canonicalPathFile.startsWith(downloadsSharedDir)) + || (documentsSharedDir != null && canonicalPathFile.startsWith(documentsSharedDir))) { return APP } diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt index c3acf42568..54fc56fa3e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/directory/FilesystemDirectoryAccess.kt @@ -54,6 +54,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): private data class DirData(val dirFile: File, val files: Array<File>, var current: Int = 0) + private val storageScopeIdentifier = StorageScope.Identifier(context) private val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager private var lastDirId = STARTING_DIR_ID private val dirs = SparseArray<DirData>() @@ -62,7 +63,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): // Directory access is available for shared storage on Android 11+ // On Android 10, access is also available as long as the `requestLegacyExternalStorage` // tag is available. - return StorageScope.getStorageScope(context, path) != StorageScope.UNKNOWN + return storageScopeIdentifier.identifyStorageScope(path) != StorageScope.UNKNOWN } override fun hasDirId(dirId: Int) = dirs.indexOfKey(dirId) >= 0 @@ -102,7 +103,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): } } - override fun fileExists(path: String) = FileAccessHandler.fileExists(context, path) + override fun fileExists(path: String) = FileAccessHandler.fileExists(context, storageScopeIdentifier, path) override fun dirNext(dirId: Int): String { val dirData = dirs[dirId] @@ -199,7 +200,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): if (fromFile.isDirectory) { fromFile.renameTo(File(to)) } else { - FileAccessHandler.renameFile(context, from, to) + FileAccessHandler.renameFile(context, storageScopeIdentifier, from, to) } } catch (e: SecurityException) { false @@ -218,7 +219,7 @@ internal class FilesystemDirectoryAccess(private val context: Context): if (deleteFile.isDirectory) { deleteFile.delete() } else { - FileAccessHandler.removeFile(context, filename) + FileAccessHandler.removeFile(context, storageScopeIdentifier, filename) } } else { true diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt index aef1bed8ce..463dabfb23 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/io/file/DataAccess.kt @@ -161,8 +161,9 @@ internal abstract class DataAccess(private val filePath: String) { fun read(buffer: ByteBuffer): Int { return try { val readBytes = fileChannel.read(buffer) + endOfFile = readBytes == -1 + || (fileChannel.position() >= fileChannel.size() && fileChannel.size() > 0) if (readBytes == -1) { - endOfFile = true 0 } else { readBytes 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 a4e0a82d6e..04b6772c45 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 @@ -49,8 +49,8 @@ class FileAccessHandler(val context: Context) { private const val INVALID_FILE_ID = 0 private const val STARTING_FILE_ID = 1 - fun fileExists(context: Context, path: String?): Boolean { - val storageScope = StorageScope.getStorageScope(context, path) + internal fun fileExists(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean { + val storageScope = storageScopeIdentifier.identifyStorageScope(path) if (storageScope == StorageScope.UNKNOWN) { return false } @@ -62,8 +62,8 @@ class FileAccessHandler(val context: Context) { } } - fun removeFile(context: Context, path: String?): Boolean { - val storageScope = StorageScope.getStorageScope(context, path) + internal fun removeFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, path: String?): Boolean { + val storageScope = storageScopeIdentifier.identifyStorageScope(path) if (storageScope == StorageScope.UNKNOWN) { return false } @@ -75,8 +75,8 @@ class FileAccessHandler(val context: Context) { } } - fun renameFile(context: Context, from: String?, to: String?): Boolean { - val storageScope = StorageScope.getStorageScope(context, from) + internal fun renameFile(context: Context, storageScopeIdentifier: StorageScope.Identifier, from: String?, to: String?): Boolean { + val storageScope = storageScopeIdentifier.identifyStorageScope(from) if (storageScope == StorageScope.UNKNOWN) { return false } @@ -89,13 +89,14 @@ class FileAccessHandler(val context: Context) { } } + private val storageScopeIdentifier = StorageScope.Identifier(context) private val files = SparseArray<DataAccess>() private var lastFileId = STARTING_FILE_ID private fun hasFileId(fileId: Int) = files.indexOfKey(fileId) >= 0 fun fileOpen(path: String?, modeFlags: Int): Int { - val storageScope = StorageScope.getStorageScope(context, path) + val storageScope = storageScopeIdentifier.identifyStorageScope(path) if (storageScope == StorageScope.UNKNOWN) { return INVALID_FILE_ID } @@ -162,10 +163,10 @@ class FileAccessHandler(val context: Context) { files[fileId].flush() } - fun fileExists(path: String?) = Companion.fileExists(context, path) + fun fileExists(path: String?) = Companion.fileExists(context, storageScopeIdentifier, path) fun fileLastModified(filepath: String?): Long { - val storageScope = StorageScope.getStorageScope(context, filepath) + val storageScope = storageScopeIdentifier.identifyStorageScope(filepath) if (storageScope == StorageScope.UNKNOWN) { return 0L } |