mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-21 16:32:39 +00:00
found a better way to load libraries
This commit is contained in:
4 files changed
+25
-76
No files matched your search
@@ -23,5 +23,3 @@ if(NOT dobby_POPULATED)
|
||||
target_include_directories(launcherfix PRIVATE ${dobby_SOURCE_DIR}/include)
|
||||
target_link_libraries(launcherfix dobby)
|
||||
endif()
|
||||
|
||||
target_link_libraries(launcherfix log)
|
||||
@@ -1,9 +1,6 @@
|
||||
#include <android/dlext.h>
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef DISABLE_LAUNCHER_FIX
|
||||
#include <dobby.h>
|
||||
@@ -51,36 +48,6 @@ JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_setOriginalDataPath(
|
||||
env->ReleaseStringUTFChars(data_path, data_path_str);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL Java_com_geode_launcher_LauncherFix_loadLibraryFromOffset(JNIEnv *env, jobject, jstring library_name, jint fd, jlong offset) {
|
||||
// loads a given library at an offset and file descriptor
|
||||
// assumes we have ownership of the file passed in fd
|
||||
|
||||
auto is_copy = jboolean();
|
||||
auto library_cname = env->GetStringUTFChars(library_name, &is_copy);
|
||||
|
||||
android_dlextinfo ext_info{};
|
||||
ext_info.flags = ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET;
|
||||
ext_info.library_fd = fd;
|
||||
ext_info.library_fd_offset = offset;
|
||||
|
||||
auto handle = android_dlopen_ext(library_cname, RTLD_NOW | RTLD_GLOBAL, &ext_info);
|
||||
env->ReleaseStringUTFChars(library_name, library_cname);
|
||||
close(fd);
|
||||
|
||||
if (handle == nullptr) {
|
||||
auto error = dlerror();
|
||||
__android_log_print(ANDROID_LOG_WARN, "GeodeLauncher-Fix", "dlopen_ext failed. given: %s\n", error);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// we don't need the library anymore
|
||||
dlclose(handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string redirect_path(const char* pathname) {
|
||||
auto data_path = DataPaths::get_instance().data_path;
|
||||
auto original_data_path = DataPaths::get_instance().original_data_path;
|
||||
|
||||
@@ -2,15 +2,14 @@ package com.geode.launcher
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageInfo
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.FileUtils
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -118,22 +117,33 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
||||
|
||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||
private fun tryLoadLibrary(packageInfo: PackageInfo, libraryName: String) {
|
||||
try {
|
||||
val nativeDir = packageInfo.applicationInfo.nativeLibraryDir
|
||||
System.load("$nativeDir/lib$libraryName.so")
|
||||
} catch (ule: UnsatisfiedLinkError) {
|
||||
loadLibraryFromAssets(libraryName)
|
||||
}
|
||||
val nativeDir = getNativeLibraryDirectory(packageInfo.applicationInfo)
|
||||
System.load("$nativeDir/lib$libraryName.so")
|
||||
}
|
||||
|
||||
private fun loadLibraryFromAssets(libraryName: String) {
|
||||
// for split apks, loads a library stored inside of the apk
|
||||
// maybe todo: is there really no way to load these libraries without weird workarounds?
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
loadLibraryFromAssetsNative(libraryName)
|
||||
} else {
|
||||
loadLibraryFromAssetsCopy(libraryName)
|
||||
private fun getNativeLibraryDirectory(applicationInfo: ApplicationInfo): String {
|
||||
// native libraries have been extracted, so the path is same as usual
|
||||
if (applicationInfo.flags and ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS == ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) {
|
||||
return applicationInfo.nativeLibraryDir
|
||||
}
|
||||
|
||||
// might be split apks, select the best path for the library
|
||||
val sourceDirs = applicationInfo.splitSourceDirs
|
||||
val architecture = LaunchUtils.getApplicationArchitecture()
|
||||
|
||||
if (!sourceDirs.isNullOrEmpty()) {
|
||||
val configAbi = architecture.replace("-", "_")
|
||||
val abiDir = sourceDirs.find { it.contains(configAbi) }
|
||||
|
||||
if (abiDir != null) {
|
||||
return "$abiDir!/lib/$architecture/"
|
||||
}
|
||||
}
|
||||
|
||||
// this configuration should never happen!
|
||||
// non split apk, but libraries are stored in apk
|
||||
val sourceDir = applicationInfo.sourceDir
|
||||
return "$sourceDir!/lib/$architecture/"
|
||||
}
|
||||
|
||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||
@@ -159,30 +169,6 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
||||
return
|
||||
}
|
||||
|
||||
private fun loadLibraryFromAssetsNative(libraryName: String) {
|
||||
// loads a library loaded in assets (which points to the apk + an offset)
|
||||
// these libraries are available to the application after merging
|
||||
|
||||
val arch = LaunchUtils.getApplicationArchitecture()
|
||||
val libraryFd = try {
|
||||
assets.openNonAssetFd("lib/$arch/lib$libraryName.so")
|
||||
} catch (_: Exception) {
|
||||
throw UnsatisfiedLinkError("Could not find library lib$libraryName.so for abi $arch")
|
||||
}
|
||||
|
||||
val fdOffset = libraryFd.startOffset
|
||||
val fdDescriptor = libraryFd.parcelFileDescriptor.detachFd()
|
||||
|
||||
if (!LauncherFix.loadLibraryFromOffset("lib$libraryName.so", fdDescriptor, fdOffset)) {
|
||||
throw UnsatisfiedLinkError("Failed to load asset lib$libraryName.so")
|
||||
}
|
||||
|
||||
// after the library is opened in native code, it should be available for loading
|
||||
// you can read more about the behavior (added in android 11):
|
||||
// https://android.googlesource.com/platform/libcore/+/7f3eb2e0ac87bdea471bc577380cf50025aebde5/ojluni/src/main/java/java/lang/Runtime.java#1060
|
||||
System.loadLibrary(libraryName)
|
||||
}
|
||||
|
||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||
private fun loadGeodeLibrary(): Boolean {
|
||||
// Load Geode if exists
|
||||
|
||||
@@ -10,6 +10,4 @@ object LauncherFix {
|
||||
external fun setDataPath(dataPath: String)
|
||||
|
||||
external fun setOriginalDataPath(dataPath: String)
|
||||
|
||||
external fun loadLibraryFromOffset(libraryName: String, fd: Int, offset: Long): Boolean
|
||||
}
|
||||
Reference in new issue
Block a user