You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-20 14:45:44 +00:00
Merge pull request #64420 from m4gr3d/investigate_read_write_access_loss_3x
[3.x] Fix issue preventing the Android Editor from displaying the project content
This commit is contained in:
@@ -228,6 +228,7 @@ static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/instal
|
|||||||
static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk'
|
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 = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
|
static const int DEFAULT_TARGET_SDK_VERSION = 32; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk'
|
||||||
|
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
|
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
|
||||||
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
|
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
|
||||||
|
|
||||||
@@ -259,7 +260,6 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ANDROID_ENABLED
|
|
||||||
// Check for devices updates
|
// Check for devices updates
|
||||||
String adb = get_adb_path();
|
String adb = get_adb_path();
|
||||||
if (FileAccess::exists(adb)) {
|
if (FileAccess::exists(adb)) {
|
||||||
@@ -373,7 +373,6 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
|
|||||||
|
|
||||||
ea->device_lock.unlock();
|
ea->device_lock.unlock();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t sleep = 300'000;
|
uint64_t sleep = 300'000;
|
||||||
uint64_t wait = 3'000'000;
|
uint64_t wait = 3'000'000;
|
||||||
@@ -386,7 +385,6 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ANDROID_ENABLED
|
|
||||||
if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) {
|
if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) {
|
||||||
String adb = get_adb_path();
|
String adb = get_adb_path();
|
||||||
if (!FileAccess::exists(adb)) {
|
if (!FileAccess::exists(adb)) {
|
||||||
@@ -397,8 +395,8 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
|
|||||||
args.push_back("kill-server");
|
args.push_back("kill-server");
|
||||||
OS::get_singleton()->execute(adb, args, true);
|
OS::get_singleton()->execute(adb, args, true);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
String EditorExportPlatformAndroid::get_project_name(const String &p_name) const {
|
String EditorExportPlatformAndroid::get_project_name(const String &p_name) const {
|
||||||
String aname;
|
String aname;
|
||||||
@@ -3452,10 +3450,14 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
|
|||||||
|
|
||||||
devices_changed.set();
|
devices_changed.set();
|
||||||
plugins_changed.set();
|
plugins_changed.set();
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
|
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorExportPlatformAndroid::~EditorExportPlatformAndroid() {
|
EditorExportPlatformAndroid::~EditorExportPlatformAndroid() {
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
quit_request.set();
|
quit_request.set();
|
||||||
check_for_changes_thread.wait_to_finish();
|
check_for_changes_thread.wait_to_finish();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,10 +98,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
|||||||
Vector<Device> devices;
|
Vector<Device> devices;
|
||||||
SafeFlag devices_changed;
|
SafeFlag devices_changed;
|
||||||
Mutex device_lock;
|
Mutex device_lock;
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
Thread check_for_changes_thread;
|
Thread check_for_changes_thread;
|
||||||
SafeFlag quit_request;
|
SafeFlag quit_request;
|
||||||
|
|
||||||
static void _check_for_changes_poll_thread(void *ud);
|
static void _check_for_changes_poll_thread(void *ud);
|
||||||
|
#endif
|
||||||
|
|
||||||
String get_project_name(const String &p_name) const;
|
String get_project_name(const String &p_name) const;
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ jmethodID FileAccessFilesystemJAndroid::_file_seek_end = nullptr;
|
|||||||
jmethodID FileAccessFilesystemJAndroid::_file_read = nullptr;
|
jmethodID FileAccessFilesystemJAndroid::_file_read = nullptr;
|
||||||
jmethodID FileAccessFilesystemJAndroid::_file_tell = nullptr;
|
jmethodID FileAccessFilesystemJAndroid::_file_tell = nullptr;
|
||||||
jmethodID FileAccessFilesystemJAndroid::_file_eof = nullptr;
|
jmethodID FileAccessFilesystemJAndroid::_file_eof = nullptr;
|
||||||
|
jmethodID FileAccessFilesystemJAndroid::_file_set_eof = nullptr;
|
||||||
jmethodID FileAccessFilesystemJAndroid::_file_close = nullptr;
|
jmethodID FileAccessFilesystemJAndroid::_file_close = nullptr;
|
||||||
jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
|
jmethodID FileAccessFilesystemJAndroid::_file_write = nullptr;
|
||||||
jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
|
jmethodID FileAccessFilesystemJAndroid::_file_flush = nullptr;
|
||||||
@@ -161,6 +162,16 @@ bool FileAccessFilesystemJAndroid::eof_reached() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileAccessFilesystemJAndroid::_set_eof(bool eof) {
|
||||||
|
if (_file_set_eof) {
|
||||||
|
ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
|
||||||
|
|
||||||
|
JNIEnv *env = get_jni_env();
|
||||||
|
ERR_FAIL_COND(env == nullptr);
|
||||||
|
env->CallVoidMethod(file_access_handler, _file_set_eof, id, eof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t FileAccessFilesystemJAndroid::get_8() const {
|
uint8_t FileAccessFilesystemJAndroid::get_8() const {
|
||||||
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
|
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
@@ -183,6 +194,7 @@ String FileAccessFilesystemJAndroid::get_line() const {
|
|||||||
while (true) {
|
while (true) {
|
||||||
size_t line_buffer_size = MIN(buffer_size_limit, file_size - get_position());
|
size_t line_buffer_size = MIN(buffer_size_limit, file_size - get_position());
|
||||||
if (line_buffer_size <= 0) {
|
if (line_buffer_size <= 0) {
|
||||||
|
const_cast<FileAccessFilesystemJAndroid *>(this)->_set_eof(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +321,7 @@ void FileAccessFilesystemJAndroid::setup(jobject p_file_access_handler) {
|
|||||||
_file_get_size = env->GetMethodID(cls, "fileGetSize", "(I)J");
|
_file_get_size = env->GetMethodID(cls, "fileGetSize", "(I)J");
|
||||||
_file_tell = env->GetMethodID(cls, "fileGetPosition", "(I)J");
|
_file_tell = env->GetMethodID(cls, "fileGetPosition", "(I)J");
|
||||||
_file_eof = env->GetMethodID(cls, "isFileEof", "(I)Z");
|
_file_eof = env->GetMethodID(cls, "isFileEof", "(I)Z");
|
||||||
|
_file_set_eof = env->GetMethodID(cls, "setFileEof", "(IZ)V");
|
||||||
_file_seek = env->GetMethodID(cls, "fileSeek", "(IJ)V");
|
_file_seek = env->GetMethodID(cls, "fileSeek", "(IJ)V");
|
||||||
_file_seek_end = env->GetMethodID(cls, "fileSeekFromEnd", "(IJ)V");
|
_file_seek_end = env->GetMethodID(cls, "fileSeekFromEnd", "(IJ)V");
|
||||||
_file_read = env->GetMethodID(cls, "fileRead", "(ILjava/nio/ByteBuffer;)I");
|
_file_read = env->GetMethodID(cls, "fileRead", "(ILjava/nio/ByteBuffer;)I");
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class FileAccessFilesystemJAndroid : public FileAccess {
|
|||||||
static jmethodID _file_seek_end;
|
static jmethodID _file_seek_end;
|
||||||
static jmethodID _file_tell;
|
static jmethodID _file_tell;
|
||||||
static jmethodID _file_eof;
|
static jmethodID _file_eof;
|
||||||
|
static jmethodID _file_set_eof;
|
||||||
static jmethodID _file_read;
|
static jmethodID _file_read;
|
||||||
static jmethodID _file_write;
|
static jmethodID _file_write;
|
||||||
static jmethodID _file_flush;
|
static jmethodID _file_flush;
|
||||||
@@ -55,6 +56,8 @@ class FileAccessFilesystemJAndroid : public FileAccess {
|
|||||||
String absolute_path;
|
String absolute_path;
|
||||||
String path_src;
|
String path_src;
|
||||||
|
|
||||||
|
void _set_eof(bool eof);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
|
virtual Error _open(const String &p_path, int p_mode_flags) override; ///< open a file
|
||||||
virtual void close() override; ///< close a file
|
virtual void close() override; ///< close a file
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
|||||||
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
|
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
|
||||||
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
||||||
|
|
||||||
GodotLib.initialize(activity, this, activity.getAssets(), io, netUtils, directoryAccessHandler, fileAccessHandler, use_apk_expansion);
|
GodotLib.initialize(activity, this, activity.getAssets(), io, netUtils, directoryAccessHandler, fileAccessHandler, use_apk_expansion, tts);
|
||||||
|
|
||||||
result_callback = null;
|
result_callback = null;
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ package org.godotengine.godot;
|
|||||||
|
|
||||||
import org.godotengine.godot.io.directory.DirectoryAccessHandler;
|
import org.godotengine.godot.io.directory.DirectoryAccessHandler;
|
||||||
import org.godotengine.godot.io.file.FileAccessHandler;
|
import org.godotengine.godot.io.file.FileAccessHandler;
|
||||||
|
import org.godotengine.godot.tts.GodotTTS;
|
||||||
import org.godotengine.godot.utils.GodotNetUtils;
|
import org.godotengine.godot.utils.GodotNetUtils;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@@ -52,7 +53,7 @@ public class GodotLib {
|
|||||||
/**
|
/**
|
||||||
* Invoked on the main thread to initialize Godot native layer.
|
* Invoked on the main thread to initialize Godot native layer.
|
||||||
*/
|
*/
|
||||||
public static native void initialize(Activity activity, Godot p_instance, AssetManager p_asset_manager, GodotIO godotIO, GodotNetUtils netUtils, DirectoryAccessHandler directoryAccessHandler, FileAccessHandler fileAccessHandler, boolean use_apk_expansion);
|
public static native void initialize(Activity activity, Godot p_instance, AssetManager p_asset_manager, GodotIO godotIO, GodotNetUtils netUtils, DirectoryAccessHandler directoryAccessHandler, FileAccessHandler fileAccessHandler, boolean use_apk_expansion, GodotTTS tts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked on the main thread to clean up Godot native layer.
|
* Invoked on the main thread to clean up Godot native layer.
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ internal abstract class DataAccess(private val filePath: String) {
|
|||||||
|
|
||||||
protected abstract val fileChannel: FileChannel
|
protected abstract val fileChannel: FileChannel
|
||||||
internal var endOfFile = false
|
internal var endOfFile = false
|
||||||
private set
|
|
||||||
|
|
||||||
fun close() {
|
fun close() {
|
||||||
try {
|
try {
|
||||||
@@ -125,9 +124,7 @@ internal abstract class DataAccess(private val filePath: String) {
|
|||||||
fun seek(position: Long) {
|
fun seek(position: Long) {
|
||||||
try {
|
try {
|
||||||
fileChannel.position(position)
|
fileChannel.position(position)
|
||||||
if (position <= size()) {
|
endOfFile = position >= fileChannel.size()
|
||||||
endOfFile = false
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(TAG, "Exception when seeking file $filePath.", e)
|
Log.w(TAG, "Exception when seeking file $filePath.", e)
|
||||||
}
|
}
|
||||||
@@ -161,8 +158,7 @@ internal abstract class DataAccess(private val filePath: String) {
|
|||||||
fun read(buffer: ByteBuffer): Int {
|
fun read(buffer: ByteBuffer): Int {
|
||||||
return try {
|
return try {
|
||||||
val readBytes = fileChannel.read(buffer)
|
val readBytes = fileChannel.read(buffer)
|
||||||
endOfFile = readBytes == -1
|
endOfFile = readBytes == -1 || (fileChannel.position() >= fileChannel.size())
|
||||||
|| (fileChannel.position() >= fileChannel.size() && fileChannel.size() > 0)
|
|
||||||
if (readBytes == -1) {
|
if (readBytes == -1) {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -194,6 +194,11 @@ class FileAccessHandler(val context: Context) {
|
|||||||
return files[fileId].endOfFile
|
return files[fileId].endOfFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setFileEof(fileId: Int, eof: Boolean) {
|
||||||
|
val file = files[fileId] ?: return
|
||||||
|
file.endOfFile = eof
|
||||||
|
}
|
||||||
|
|
||||||
fun fileClose(fileId: Int) {
|
fun fileClose(fileId: Int) {
|
||||||
if (hasFileId(fileId)) {
|
if (hasFileId(fileId)) {
|
||||||
files[fileId].close()
|
files[fileId].close()
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion) {
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion, jobject p_godot_tts) {
|
||||||
JavaVM *jvm;
|
JavaVM *jvm;
|
||||||
env->GetJavaVM(&jvm);
|
env->GetJavaVM(&jvm);
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
|
|||||||
DirAccessJAndroid::setup(p_directory_access_handler);
|
DirAccessJAndroid::setup(p_directory_access_handler);
|
||||||
FileAccessFilesystemJAndroid::setup(p_file_access_handler);
|
FileAccessFilesystemJAndroid::setup(p_file_access_handler);
|
||||||
NetSocketAndroid::setup(p_net_utils);
|
NetSocketAndroid::setup(p_net_utils);
|
||||||
TTS_Android::setup(godot_java->get_member_object("tts", "Lorg/godotengine/godot/tts/GodotTTS;", env));
|
TTS_Android::setup(p_godot_tts);
|
||||||
|
|
||||||
os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion);
|
os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion);
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
|
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
|
||||||
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
|
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject p_activity, jobject p_godot_instance, jobject p_asset_manager, jobject p_godot_io, jobject p_net_utils, jobject p_directory_access_handler, jobject p_file_access_handler, jboolean p_use_apk_expansion, jobject p_godot_tts);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
|
||||||
|
|||||||
@@ -57,8 +57,10 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
|
|||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
SafeFlag plugins_changed;
|
SafeFlag plugins_changed;
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
Thread check_for_changes_thread;
|
Thread check_for_changes_thread;
|
||||||
SafeFlag quit_request;
|
SafeFlag quit_request;
|
||||||
|
#endif
|
||||||
Mutex plugins_lock;
|
Mutex plugins_lock;
|
||||||
Vector<PluginConfigIOS> plugins;
|
Vector<PluginConfigIOS> plugins;
|
||||||
|
|
||||||
@@ -142,6 +144,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
static void _check_for_changes_poll_thread(void *ud) {
|
static void _check_for_changes_poll_thread(void *ud) {
|
||||||
EditorExportPlatformIOS *ea = (EditorExportPlatformIOS *)ud;
|
EditorExportPlatformIOS *ea = (EditorExportPlatformIOS *)ud;
|
||||||
|
|
||||||
@@ -177,6 +180,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
|
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
|
||||||
@@ -2171,12 +2175,16 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() {
|
|||||||
|
|
||||||
plugins_changed.set();
|
plugins_changed.set();
|
||||||
|
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
|
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorExportPlatformIOS::~EditorExportPlatformIOS() {
|
EditorExportPlatformIOS::~EditorExportPlatformIOS() {
|
||||||
|
#ifndef ANDROID_ENABLED
|
||||||
quit_request.set();
|
quit_request.set();
|
||||||
check_for_changes_thread.wait_to_finish();
|
check_for_changes_thread.wait_to_finish();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_iphone_exporter() {
|
void register_iphone_exporter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user