fix bugs
This commit is contained in:
parent
a4dc7ff1e8
commit
fda90e332a
|
@ -100,7 +100,11 @@
|
|||
android:screenOrientation="sensorLandscape"/>
|
||||
<service
|
||||
android:name="com.tungsten.fclcore.download.ProcessService"
|
||||
android:process=":processService" />
|
||||
android:process=":processService"
|
||||
android:launchMode="standard"
|
||||
android:multiprocess="true"
|
||||
android:alwaysRetainTaskState="true"
|
||||
android:enabled="true"/>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="@string/file_browser_provider"
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.tungsten.fclcore.event.Event;
|
|||
import com.tungsten.fclcore.fakefx.beans.property.ObjectProperty;
|
||||
import com.tungsten.fclcore.fakefx.beans.property.SimpleObjectProperty;
|
||||
import com.tungsten.fclcore.fakefx.beans.value.ObservableValue;
|
||||
import com.tungsten.fclcore.task.Schedulers;
|
||||
import com.tungsten.fclcore.util.Logging;
|
||||
import com.tungsten.fclcore.util.fakefx.BindingMapping;
|
||||
import com.tungsten.fcllibrary.component.FCLActivity;
|
||||
|
@ -306,6 +307,6 @@ public class MainActivity extends FCLActivity implements FCLMenuView.OnSelectLis
|
|||
}
|
||||
|
||||
private void setupVersionDisplay() {
|
||||
holder.add(FXUtils.onWeakChangeAndOperate(Profiles.selectedVersionProperty(), this::loadVersion));
|
||||
holder.add(FXUtils.onWeakChangeAndOperate(Profiles.selectedVersionProperty(), s -> Schedulers.androidUIThread().execute(() -> loadVersion(s))));
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import static com.tungsten.fclcore.util.Lang.tryCast;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -40,6 +41,7 @@ import com.tungsten.fclcore.task.TaskListener;
|
|||
import com.tungsten.fclcore.util.Lang;
|
||||
import com.tungsten.fclcore.util.StringUtils;
|
||||
import com.tungsten.fcllibrary.component.FCLAdapter;
|
||||
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
|
||||
import com.tungsten.fcllibrary.component.view.FCLImageView;
|
||||
import com.tungsten.fcllibrary.component.view.FCLProgressBar;
|
||||
import com.tungsten.fcllibrary.component.view.FCLTextView;
|
||||
|
@ -225,6 +227,16 @@ public final class TaskListPane extends FCLAdapter {
|
|||
title = parent.findViewById(R.id.title);
|
||||
icon = parent.findViewById(R.id.icon);
|
||||
|
||||
int[][] state = {
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
int[] color = {
|
||||
ThemeEngine.getSystemAutoTint(context)
|
||||
};
|
||||
icon.setImageTintList(new ColorStateList(state, color));
|
||||
|
||||
String stageKey = StringUtils.substringBefore(stage, ':');
|
||||
String stageValue = StringUtils.substringAfter(stage, ':');
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.tungsten.fclcore.download;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
|
@ -10,7 +9,6 @@ import androidx.annotation.Nullable;
|
|||
import com.tungsten.fclauncher.FCLConfig;
|
||||
import com.tungsten.fclauncher.FCLauncher;
|
||||
import com.tungsten.fclauncher.bridge.FCLBridgeCallback;
|
||||
import com.tungsten.fclauncher.FCLPath;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
|
@ -28,13 +26,20 @@ public class ProcessService extends Service {
|
|||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
FCLPath.loadPaths(getApplicationContext());
|
||||
String[] commands = intent.getExtras().getStringArray("commands");
|
||||
startProcess(getApplicationContext(), commands);
|
||||
System.out.println("ProcessService started!");
|
||||
String[] command = intent.getExtras().getStringArray("command");
|
||||
FCLConfig config = new FCLConfig(
|
||||
getApplicationContext(),
|
||||
getApplicationContext().getExternalFilesDir("log").getAbsolutePath(),
|
||||
getApplicationContext().getDir("runtime", 0).getAbsolutePath() + "/java/jre8",
|
||||
getApplicationContext().getCacheDir() + "/fclauncher",
|
||||
null,
|
||||
command);
|
||||
startProcess(config);
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
public void startProcess(Context context, String[] args) {
|
||||
public void startProcess(FCLConfig config) {
|
||||
FCLBridgeCallback callback = new FCLBridgeCallback() {
|
||||
@Override
|
||||
public void onCursorModeChange(int mode) {
|
||||
|
@ -56,13 +61,6 @@ public class ProcessService extends Service {
|
|||
android.os.Process.killProcess(android.os.Process.myPid());
|
||||
}
|
||||
};
|
||||
FCLConfig config = new FCLConfig(
|
||||
context,
|
||||
FCLPath.LOG_DIR,
|
||||
FCLPath.JAVA_8_PATH,
|
||||
FCLPath.CACHE_DIR,
|
||||
null,
|
||||
args);
|
||||
FCLauncher.launchAPIInstaller(config, callback);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
|
@ -140,9 +141,11 @@ public class ForgeNewInstallTask extends Task<Version> {
|
|||
|
||||
LOG.info("Executing external processor " + processor.getJar().toString() + ", command line: " + new CommandBuilder().addAll(command).toString());
|
||||
int exitCode;
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
SocketServer server = new SocketServer("127.0.0.1", ProcessService.PROCESS_SERVICE_PORT, (server1, msg) -> {
|
||||
server1.setResult(msg);
|
||||
server1.stop();
|
||||
latch.countDown();
|
||||
});
|
||||
Intent service = new Intent(FCLPath.CONTEXT, ProcessService.class);
|
||||
Bundle bundle = new Bundle();
|
||||
|
@ -150,6 +153,7 @@ public class ForgeNewInstallTask extends Task<Version> {
|
|||
service.putExtras(bundle);
|
||||
FCLPath.CONTEXT.startService(service);
|
||||
server.start();
|
||||
latch.await();
|
||||
exitCode = (int) server.getResult();
|
||||
if (exitCode != 0)
|
||||
throw new IOException("Game processor exited abnormally with code " + exitCode);
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.tungsten.fclcore.game.Library;
|
|||
import com.tungsten.fclcore.game.Version;
|
||||
import com.tungsten.fclcore.task.FileDownloadTask;
|
||||
import com.tungsten.fclcore.task.Task;
|
||||
import com.tungsten.fclcore.util.LibFilter;
|
||||
import com.tungsten.fclcore.util.Logging;
|
||||
import com.tungsten.fclcore.util.io.FileUtils;
|
||||
|
||||
|
@ -46,9 +47,9 @@ public final class GameLibrariesTask extends Task<Void> {
|
|||
*/
|
||||
public GameLibrariesTask(AbstractDependencyManager dependencyManager, Version version, boolean integrityCheck, List<Library> libraries) {
|
||||
this.dependencyManager = dependencyManager;
|
||||
this.version = version;
|
||||
this.version = LibFilter.filter(version);
|
||||
this.integrityCheck = integrityCheck;
|
||||
this.libraries = libraries;
|
||||
this.libraries = LibFilter.filterLibs(libraries);
|
||||
|
||||
setSignificance(TaskSignificance.MODERATE);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||
else
|
||||
throw new LibraryDownloadException(library, t);
|
||||
} else {
|
||||
if (xz) unpackLibrary(jar, Files.readAllBytes(xzFile.toPath()));
|
||||
// if (xz) unpackLibrary(jar, Files.readAllBytes(xzFile.toPath()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,6 +255,8 @@ public class LibraryDownloadTask extends Task<Void> {
|
|||
jos.closeEntry();
|
||||
}
|
||||
|
||||
Files.delete(temp);
|
||||
if (temp.toFile().exists()) {
|
||||
Files.delete(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import java.nio.file.FileSystem;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* <b>Note</b>: OptiFine should be installed in the end.
|
||||
|
@ -141,16 +142,19 @@ public final class OptiFineInstallTask extends Task<Version> {
|
|||
gameRepository.getLibraryFile(version, optiFineLibrary).toString()
|
||||
};
|
||||
int exitCode;
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
SocketServer server = new SocketServer("127.0.0.1", ProcessService.PROCESS_SERVICE_PORT, (server1, msg) -> {
|
||||
server1.setResult(msg);
|
||||
server1.stop();
|
||||
latch.countDown();
|
||||
});
|
||||
Intent service = new Intent(FCLPath.CONTEXT, ProcessService.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putStringArray("commands", command);
|
||||
bundle.putStringArray("command", command);
|
||||
service.putExtras(bundle);
|
||||
FCLPath.CONTEXT.startService(service);
|
||||
server.start();
|
||||
latch.await();
|
||||
exitCode = (int) server.getResult();
|
||||
if (exitCode != 0)
|
||||
throw new IOException("OptiFine patcher failed, command: " + new CommandBuilder().addAll(Arrays.asList(command)));
|
||||
|
|
|
@ -4,17 +4,22 @@ import com.tungsten.fclcore.game.Library;
|
|||
import com.tungsten.fclcore.game.Version;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LibFilter {
|
||||
|
||||
public static Version filter(Version version) {
|
||||
return version.setLibraries(filterLibs(version.getLibraries()));
|
||||
}
|
||||
|
||||
public static List<Library> filterLibs(List<Library> libraries) {
|
||||
ArrayList<Library> newLibraries = new ArrayList<>();
|
||||
for (Library library : version.getLibraries()) {
|
||||
for (Library library : libraries) {
|
||||
if (!library.isNative() && !library.getName().contains("net.java.jinput") && !library.getName().contains("org.lwjgl") && !library.getName().contains("platform")) {
|
||||
newLibraries.add(library);
|
||||
}
|
||||
}
|
||||
return version.setLibraries(newLibraries);
|
||||
return newLibraries;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.tungsten.fclcore.util;
|
||||
|
||||
import com.tungsten.fclcore.task.Schedulers;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.io.IOException;
|
||||
|
@ -11,8 +13,8 @@ import java.util.logging.Level;
|
|||
|
||||
public class SocketServer {
|
||||
|
||||
private final DatagramPacket packet;
|
||||
private final DatagramSocket socket;
|
||||
private DatagramPacket packet;
|
||||
private DatagramSocket socket;
|
||||
private final Listener listener;
|
||||
private final String ip;
|
||||
private final int port;
|
||||
|
@ -24,13 +26,19 @@ public class SocketServer {
|
|||
void onReceive(SocketServer server, String msg);
|
||||
}
|
||||
|
||||
public SocketServer(String ip, int port, Listener listener) throws UnknownHostException, SocketException {
|
||||
public SocketServer(String ip, int port, Listener listener) {
|
||||
this.listener = listener;
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
byte[] bytes = new byte[1024];
|
||||
packet = new DatagramPacket(bytes, bytes.length);
|
||||
socket = new DatagramSocket(port, InetAddress.getByName(ip));
|
||||
Schedulers.androidUIThread().execute(() -> {
|
||||
byte[] bytes = new byte[1024];
|
||||
packet = new DatagramPacket(bytes, bytes.length);
|
||||
try {
|
||||
socket = new DatagramSocket(port, InetAddress.getByName(ip));
|
||||
} catch (SocketException | UnknownHostException e) {
|
||||
Logging.LOG.log(Level.WARNING, "Failed to start socket server, error: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public DatagramPacket getPacket() {
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
|
@ -61,6 +62,14 @@ public class ThemeEngine {
|
|||
return theme;
|
||||
}
|
||||
|
||||
public static boolean isNightMode(Context context) {
|
||||
return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
|
||||
public static int getSystemAutoTint(Context context) {
|
||||
return isNightMode(context) ? Color.WHITE : Color.BLACK;
|
||||
}
|
||||
|
||||
public void applyColor(int color) {
|
||||
theme.setColor(color);
|
||||
for (View view : runnables.keySet()) {
|
||||
|
|
|
@ -2,9 +2,11 @@ package com.tungsten.fclauncher;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
public class FCLConfig {
|
||||
import java.io.Serializable;
|
||||
|
||||
public enum Renderer {
|
||||
public class FCLConfig implements Serializable {
|
||||
|
||||
public enum Renderer implements Serializable {
|
||||
RENDERER_GL4ES("libgl4es.so:libgl4es_egl.so"),
|
||||
RENDERER_ZINK("libGL.so:libEGL.so");
|
||||
|
||||
|
|
|
@ -118,7 +118,8 @@ public class FCLauncher {
|
|||
argList.add(0, config.getJavaPath() + "/bin/java");
|
||||
String[] args = new String[argList.size()];
|
||||
for (int i = 0; i < argList.size(); i++) {
|
||||
args[i] = argList.get(i).replace("${natives_directory}", getLibraryPath(config.getContext(), config.getJavaPath())).replace("${gl_lib_name}", config.getRenderer().getGlLibName());
|
||||
String a = argList.get(i).replace("${natives_directory}", getLibraryPath(config.getContext(), config.getJavaPath()));
|
||||
args[i] = config.getRenderer() == null ? a : a.replace("${gl_lib_name}", config.getRenderer().getGlLibName());
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
@ -179,6 +180,24 @@ public class FCLauncher {
|
|||
bridge.dlopen(jreLibDir + "/libfontmanager.so");
|
||||
bridge.dlopen(jreLibDir + "/libtinyiconv.so");
|
||||
bridge.dlopen(jreLibDir + "/libinstrument.so");
|
||||
for(File file : locateLibs(new File(config.getJavaPath()))) {
|
||||
bridge.dlopen(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<File> locateLibs(File path) {
|
||||
ArrayList<File> returnValue = new ArrayList<>();
|
||||
File[] list = path.listFiles();
|
||||
if (list != null) {
|
||||
for (File f : list) {
|
||||
if (f.isFile() && f.getName().endsWith(".so")) {
|
||||
returnValue.add(f);
|
||||
} else if(f.isDirectory()) {
|
||||
returnValue.addAll(locateLibs(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private static void setupGraphicAndSoundEngine(FCLConfig config, FCLBridge bridge) {
|
||||
|
@ -203,6 +222,8 @@ public class FCLauncher {
|
|||
System.out.println(task + " argument: " + arg);
|
||||
}
|
||||
bridge.setupJLI();
|
||||
bridge.setLdLibraryPath(getLibraryPath(config.getContext(), config.getJavaPath()));
|
||||
System.out.println("Hook exit " + (bridge.setupExitTrap(bridge) == 0 ? "success" : "failed"));
|
||||
System.out.println("OpenJDK exited with code : " + bridge.jliLaunch(args));
|
||||
}
|
||||
|
||||
|
@ -227,9 +248,6 @@ public class FCLauncher {
|
|||
// setup graphic and sound engine
|
||||
setupGraphicAndSoundEngine(config, bridge);
|
||||
|
||||
// hook exit
|
||||
bridge.setupExitTrap(bridge);
|
||||
|
||||
// set working directory
|
||||
System.out.println("Working directory: " + config.getWorkingDir());
|
||||
bridge.chdir(config.getWorkingDir());
|
||||
|
@ -268,9 +286,6 @@ public class FCLauncher {
|
|||
// setup graphic and sound engine
|
||||
setupGraphicAndSoundEngine(config, bridge);
|
||||
|
||||
// hook exit
|
||||
bridge.setupExitTrap(bridge);
|
||||
|
||||
// set working directory
|
||||
System.out.println("Working directory: " + config.getWorkingDir());
|
||||
bridge.chdir(config.getWorkingDir());
|
||||
|
@ -305,9 +320,6 @@ public class FCLauncher {
|
|||
// setup java runtime
|
||||
setUpJavaRuntime(config, bridge);
|
||||
|
||||
// hook exit
|
||||
bridge.setupExitTrap(bridge);
|
||||
|
||||
// set working directory
|
||||
System.out.println("Working directory: " + config.getWorkingDir());
|
||||
bridge.chdir(config.getWorkingDir());
|
||||
|
|
|
@ -60,7 +60,8 @@ public class FCLBridge implements Serializable {
|
|||
public native int chdir(String path);
|
||||
public native void setenv(String key, String value);
|
||||
public native int dlopen(String path);
|
||||
public native void setupExitTrap(FCLBridge bridge);
|
||||
public native void setLdLibraryPath(String path);
|
||||
public native int setupExitTrap(FCLBridge bridge);
|
||||
public native void setEventPipe();
|
||||
public native void pushEvent(long time, int type, int keycode, int keyChar);
|
||||
public native void setupJLI();
|
||||
|
@ -108,7 +109,7 @@ public class FCLBridge implements Serializable {
|
|||
}
|
||||
|
||||
// Loader function
|
||||
public void exit(int code) {
|
||||
public void onExit(int code) {
|
||||
if (callback != null) {
|
||||
callback.onExit(code);
|
||||
}
|
||||
|
|
|
@ -23,21 +23,12 @@ static const jboolean const_cpwildcard = JNI_TRUE;
|
|||
static const jboolean const_javaw = JNI_FALSE;
|
||||
static const jint const_ergo_class = 0; //DEFAULT_POLICY
|
||||
|
||||
typedef void (*android_update_LD_LIBRARY_PATH_t)(const char*);
|
||||
static volatile jobject exitTrap_bridge;
|
||||
static volatile jmethodID exitTrap_method;
|
||||
static JavaVM *exitTrap_jvm;
|
||||
|
||||
void (*old_exit)(int code);
|
||||
void custom_exit(int code) {
|
||||
JNIEnv *env;
|
||||
(*exitTrap_jvm)->AttachCurrentThread(exitTrap_jvm, &env, NULL);
|
||||
(*env)->CallVoidMethod(env, exitTrap_bridge, exitTrap_method, code);
|
||||
(*env)->DeleteGlobalRef(env, exitTrap_bridge);
|
||||
(*exitTrap_jvm)->DetachCurrentThread(exitTrap_jvm);
|
||||
old_exit(code);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStdio(JNIEnv* env, jclass clazz, jstring path) {
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStdio(JNIEnv* env, jobject jobject, jstring path) {
|
||||
char const* file = (*env)->GetStringUTFChars(env, path, 0);
|
||||
|
||||
int fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
|
@ -47,7 +38,7 @@ JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_redirectStd
|
|||
(*env)->ReleaseStringUTFChars(env, path, file);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_chdir(JNIEnv* env, jclass clazz, jstring path) {
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_chdir(JNIEnv* env, jobject jobject, jstring path) {
|
||||
char const* dir = (*env)->GetStringUTFChars(env, path, 0);
|
||||
|
||||
int b = chdir(dir);
|
||||
|
@ -56,7 +47,7 @@ JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_chdir(JNIEn
|
|||
return b;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setenv(JNIEnv* env, jclass clazz, jstring str1, jstring str2) {
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setenv(JNIEnv* env, jobject jobject, jstring str1, jstring str2) {
|
||||
char const* name = (*env)->GetStringUTFChars(env, str1, 0);
|
||||
char const* value = (*env)->GetStringUTFChars(env, str2, 0);
|
||||
|
||||
|
@ -66,7 +57,7 @@ JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setenv(JNIE
|
|||
(*env)->ReleaseStringUTFChars(env, str2, value);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_dlopen(JNIEnv* env, jclass clazz, jstring str) {
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_dlopen(JNIEnv* env, jobject jobject, jstring str) {
|
||||
dlerror();
|
||||
|
||||
int ret = 0;
|
||||
|
@ -74,7 +65,7 @@ JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_dlopen(JNIE
|
|||
|
||||
void* handle;
|
||||
dlerror();
|
||||
handle = dlopen(lib_name, RTLD_GLOBAL);
|
||||
handle = dlopen(lib_name, RTLD_GLOBAL | RTLD_LAZY);
|
||||
__android_log_print(dlerror() == NULL ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "loading %s (error = %s)", lib_name, dlerror());
|
||||
|
||||
if (handle == NULL) {
|
||||
|
@ -85,15 +76,40 @@ JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_dlopen(JNIE
|
|||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setupExitTrap(JNIEnv *env, jclass clazz, jobject bridge) {
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setLdLibraryPath(JNIEnv *env, jobject jobject, jstring ldLibraryPath) {
|
||||
android_update_LD_LIBRARY_PATH_t android_update_LD_LIBRARY_PATH;
|
||||
void *libdl_handle = dlopen("libdl.so", RTLD_LAZY);
|
||||
void *updateLdLibPath = dlsym(libdl_handle, "android_update_LD_LIBRARY_PATH");
|
||||
if (updateLdLibPath == NULL) {
|
||||
updateLdLibPath = dlsym(libdl_handle, "__loader_android_update_LD_LIBRARY_PATH");
|
||||
__android_log_print(dlerror() == NULL ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "loading %s (error = %s)", "libdl.so", dlerror());
|
||||
}
|
||||
android_update_LD_LIBRARY_PATH = (android_update_LD_LIBRARY_PATH_t) updateLdLibPath;
|
||||
const char* ldLibPathUtf = (*env)->GetStringUTFChars(env, ldLibraryPath, 0);
|
||||
android_update_LD_LIBRARY_PATH(ldLibPathUtf);
|
||||
(*env)->ReleaseStringUTFChars(env, ldLibraryPath, ldLibPathUtf);
|
||||
}
|
||||
|
||||
void (*old_exit)(int code);
|
||||
void custom_exit(int code) {
|
||||
__android_log_print(code == 0 ? ANDROID_LOG_INFO : ANDROID_LOG_ERROR, "FCL", "JVM exit with code %d.", code);
|
||||
JNIEnv *env;
|
||||
(*exitTrap_jvm)->AttachCurrentThread(exitTrap_jvm, &env, NULL);
|
||||
(*env)->CallVoidMethod(env, exitTrap_bridge, exitTrap_method, code);
|
||||
(*env)->DeleteGlobalRef(env, exitTrap_bridge);
|
||||
(*exitTrap_jvm)->DetachCurrentThread(exitTrap_jvm);
|
||||
old_exit(code);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setupExitTrap(JNIEnv *env, jobject jobject1, jobject bridge) {
|
||||
exitTrap_bridge = (*env)->NewGlobalRef(env, bridge);
|
||||
(*env)->GetJavaVM(env, &exitTrap_jvm);
|
||||
jclass exitTrap_exitClass = (*env)->NewGlobalRef(env,(*env)->FindClass(env, "com/tungsten/fclauncher/bridge/FCLBridge"));
|
||||
exitTrap_method = (*env)->GetMethodID(env, exitTrap_exitClass, "exit", "(I)V");
|
||||
exitTrap_method = (*env)->GetMethodID(env, exitTrap_exitClass, "onExit", "(I)V");
|
||||
(*env)->DeleteGlobalRef(env, exitTrap_exitClass);
|
||||
// xhook_enable_debug(1);
|
||||
xhook_enable_debug(1);
|
||||
xhook_register(".*\\.so$", "exit", custom_exit, (void **) &old_exit);
|
||||
xhook_refresh(1);
|
||||
return xhook_refresh(1);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -110,7 +126,7 @@ int
|
|||
jint ergo_class /* ergnomics policy */
|
||||
);
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setupJLI(JNIEnv* env, jclass clazz){
|
||||
JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setupJLI(JNIEnv* env, jobject jobject){
|
||||
|
||||
void* handle;
|
||||
handle = dlopen("libjli.so", RTLD_LAZY);
|
||||
|
@ -118,7 +134,7 @@ JNIEXPORT void JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_setupJLI(JN
|
|||
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_jliLaunch(JNIEnv *env, jclass clazz, jobjectArray argsArray){
|
||||
JNIEXPORT jint JNICALL Java_com_tungsten_fclauncher_bridge_FCLBridge_jliLaunch(JNIEnv *env, jobject jobject, jobjectArray argsArray){
|
||||
int argc = (*env)->GetArrayLength(env, argsArray);
|
||||
char* argv[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
|
|
|
@ -306,14 +306,10 @@ static void xh_core_refresh_impl()
|
|||
char line[512];
|
||||
FILE *fp;
|
||||
uintptr_t base_addr;
|
||||
uintptr_t prev_base_addr = 0;
|
||||
char perm[5];
|
||||
char prev_perm[5] = "---p";
|
||||
unsigned long offset;
|
||||
unsigned long prev_offset = 0;
|
||||
int pathname_pos;
|
||||
char *pathname;
|
||||
char prev_pathname[512] = {0};
|
||||
size_t pathname_len;
|
||||
xh_core_map_info_t *mi, *mi_tmp;
|
||||
xh_core_map_info_t mi_key;
|
||||
|
@ -332,12 +328,16 @@ static void xh_core_refresh_impl()
|
|||
{
|
||||
if(sscanf(line, "%"PRIxPTR"-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue;
|
||||
|
||||
// do not touch the shared memory
|
||||
if (perm[3] != 'p') continue;
|
||||
//check permission
|
||||
if(perm[0] != 'r') continue;
|
||||
if(perm[3] != 'p') continue; //do not touch the shared memory
|
||||
|
||||
// Ignore permission PROT_NONE maps
|
||||
if (perm[0] == '-' && perm[1] == '-' && perm[2] == '-')
|
||||
continue;
|
||||
//check offset
|
||||
//
|
||||
//We are trying to find ELF header in memory.
|
||||
//It can only be found at the beginning of a mapped memory regions
|
||||
//whose offset is 0.
|
||||
if(0 != offset) continue;
|
||||
|
||||
//get pathname
|
||||
while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1))
|
||||
|
@ -354,26 +354,6 @@ static void xh_core_refresh_impl()
|
|||
if(0 == pathname_len) continue;
|
||||
if('[' == pathname[0]) continue;
|
||||
|
||||
// Find non-executable map, we need record it. Because so maps can begin with
|
||||
// an non-executable map.
|
||||
if (perm[2] != 'x') {
|
||||
prev_offset = offset;
|
||||
prev_base_addr = base_addr;
|
||||
memcpy(prev_perm, perm, sizeof(prev_perm));
|
||||
strcpy(prev_pathname, pathname);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find executable map if offset == 0, it OK,
|
||||
// or we need check previous map for base address.
|
||||
if (offset != 0) {
|
||||
if (strcmp(prev_pathname, pathname) || prev_offset != 0 || prev_perm[0] != 'r') {
|
||||
continue;
|
||||
}
|
||||
// The previous map is real begin map
|
||||
base_addr = prev_base_addr;
|
||||
}
|
||||
|
||||
//check pathname
|
||||
//if we need to hook this elf?
|
||||
match = 0;
|
||||
|
|
Loading…
Reference in New Issue