summaryrefslogtreecommitdiffstats
path: root/platform/android/os_android.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/os_android.cpp')
-rw-r--r--platform/android/os_android.cpp71
1 files changed, 62 insertions, 9 deletions
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index c040d8c4c6..82e7fdb320 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -39,6 +39,8 @@
#include "net_socket_android.h"
#include "core/config/project_settings.h"
+#include "core/extension/gdextension_manager.h"
+#include "core/io/xml_parser.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "main/main.h"
@@ -58,10 +60,10 @@ String _remove_symlink(const String &dir) {
// Change directory to the external data directory.
chdir(dir.utf8().get_data());
// Get the actual directory without the potential symlink.
- char dir_name_wihout_symlink[2048];
- getcwd(dir_name_wihout_symlink, 2048);
+ char dir_name_without_symlink[2048];
+ getcwd(dir_name_without_symlink, 2048);
// Convert back to a String.
- String dir_without_symlink(dir_name_wihout_symlink);
+ String dir_without_symlink(dir_name_without_symlink);
// Restore original current directory.
chdir(current_dir_name);
return dir_without_symlink;
@@ -160,13 +162,41 @@ Vector<String> OS_Android::get_granted_permissions() const {
return godot_java->get_granted_permissions();
}
-Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
+Error OS_Android::open_dynamic_library(const String &p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
String path = p_path;
+ bool so_file_exists = true;
if (!FileAccess::exists(path)) {
path = p_path.get_file();
+ so_file_exists = false;
}
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
+ if (!p_library_handle && so_file_exists) {
+ // The library may be on the sdcard and thus inaccessible. Try to copy it to the internal
+ // directory.
+ uint64_t so_modified_time = FileAccess::get_modified_time(p_path);
+ String dynamic_library_path = get_dynamic_libraries_path().path_join(String::num_uint64(so_modified_time));
+ String internal_path = dynamic_library_path.path_join(p_path.get_file());
+
+ bool internal_so_file_exists = FileAccess::exists(internal_path);
+ if (!internal_so_file_exists) {
+ Ref<DirAccess> da_ref = DirAccess::create_for_path(p_path);
+ if (da_ref.is_valid()) {
+ Error create_dir_result = da_ref->make_dir_recursive(dynamic_library_path);
+ if (create_dir_result == OK || create_dir_result == ERR_ALREADY_EXISTS) {
+ internal_so_file_exists = da_ref->copy(path, internal_path) == OK;
+ }
+ }
+ }
+
+ if (internal_so_file_exists) {
+ p_library_handle = dlopen(internal_path.utf8().get_data(), RTLD_NOW);
+ if (p_library_handle) {
+ path = internal_path;
+ }
+ }
+ }
+
ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", p_path, dlerror()));
if (r_resolved_path != nullptr) {
@@ -294,15 +324,21 @@ void OS_Android::main_loop_end() {
void OS_Android::main_loop_focusout() {
DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
+ }
audio_driver_android.set_pause(true);
}
void OS_Android::main_loop_focusin() {
DisplayServerAndroid::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
+ }
audio_driver_android.set_pause(false);
}
-Error OS_Android::shell_open(String p_uri) {
+Error OS_Android::shell_open(const String &p_uri) {
return godot_io_java->open_uri(p_uri);
}
@@ -584,6 +620,10 @@ String OS_Android::get_user_data_dir() const {
return ".";
}
+String OS_Android::get_dynamic_libraries_path() const {
+ return get_cache_path().path_join("dynamic_libraries");
+}
+
String OS_Android::get_cache_path() const {
if (!cache_dir_cache.is_empty()) {
return cache_dir_cache;
@@ -674,15 +714,15 @@ String OS_Android::get_config_path() const {
return get_user_data_dir().path_join("config");
}
-void OS_Android::benchmark_begin_measure(const String &p_what) {
+void OS_Android::benchmark_begin_measure(const String &p_context, const String &p_what) {
#ifdef TOOLS_ENABLED
- godot_java->begin_benchmark_measure(p_what);
+ godot_java->begin_benchmark_measure(p_context, p_what);
#endif
}
-void OS_Android::benchmark_end_measure(const String &p_what) {
+void OS_Android::benchmark_end_measure(const String &p_context, const String &p_what) {
#ifdef TOOLS_ENABLED
- godot_java->end_benchmark_measure(p_what);
+ godot_java->end_benchmark_measure(p_context, p_what);
#endif
}
@@ -715,6 +755,11 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
return true;
}
#endif
+
+ if (godot_java->has_feature(p_feature)) {
+ return true;
+ }
+
return false;
}
@@ -791,5 +836,13 @@ Error OS_Android::setup_remote_filesystem(const String &p_server_host, int p_por
return err;
}
+void OS_Android::load_platform_gdextensions() const {
+ Vector<String> extension_list_config_file = godot_java->get_gdextension_list_config_file();
+ for (String config_file_path : extension_list_config_file) {
+ GDExtensionManager::LoadStatus err = GDExtensionManager::get_singleton()->load_extension(config_file_path);
+ ERR_CONTINUE_MSG(err == GDExtensionManager::LOAD_STATUS_FAILED, "Error loading platform extension: " + config_file_path);
+ }
+}
+
OS_Android::~OS_Android() {
}