diff --git a/app/src/main/java/net/kdt/pojavlaunch/BinaryExecutor.java b/app/src/main/java/net/kdt/pojavlaunch/BinaryExecutor.java new file mode 100644 index 000000000..6af4216ce --- /dev/null +++ b/app/src/main/java/net/kdt/pojavlaunch/BinaryExecutor.java @@ -0,0 +1,42 @@ +package net.kdt.pojavlaunch; + +import android.system.*; +import java.io.*; + +public class BinaryExecutor +{ + private BinaryExecutor() {} + + public static void initJavaRuntime() { + chdir(Tools.MAIN_PATH); + + dlopen(Tools.homeJreDir + "/lib/jli/libjli.so"); + dlopen(Tools.homeJreDir + "/lib/server/libjvm.so"); + dlopen(Tools.homeJreDir + "/lib/libverify.so"); + dlopen(Tools.homeJreDir + "/lib/libjava.so"); + dlopen(Tools.homeJreDir + "/lib/libnet.so"); + dlopen(Tools.homeJreDir + "/lib/libnio.so"); + dlopen(Tools.homeJreDir + "/lib/libawt.so"); + dlopen(Tools.homeJreDir + "/lib/libawt_headless.so"); + } + + public static FileDescriptor redirectStdio() throws ErrnoException { + File logFile = new File(Tools.MAIN_PATH, "v3log.txt"); + + FileDescriptor fd = Os.open(logFile.getAbsolutePath(), OsConstants.O_WRONLY | OsConstants.O_CREAT | OsConstants.O_TRUNC, 0666); + Os.dup2(fd, OsConstants.STDERR_FILENO); + Os.dup2(fd, OsConstants.STDOUT_FILENO); + + return fd; + } + + public static native int chdir(String path); + public static native boolean dlopen(String libPath); + + // Load and execute PIE binary using dlopen and dlsym("main") + public static native int executeBinary(String[] args); + + static { + System.loadLibrary("binexecutor"); + } +} diff --git a/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java index 6805aee1f..0ba9ae90e 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -119,6 +119,10 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, private boolean isExited = false; private boolean isLogAllow = false; private int navBarHeight = 40; + + private static final int LTYPE_INVOCATION = 0; + private static final int LTYPE_PROCESS = 1; + private final int LAUNCH_TYPE = LTYPE_INVOCATION; // private static Collection rsaPkcs1List; @@ -974,10 +978,20 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, return args; } + private ShellProcessOperation mLaunchShell; + private void setEnvironment(String name, String value) throws ErrnoException, IOException { + if (LAUNCH_TYPE == LTYPE_PROCESS) { + mLaunchShell.writeToProcess("export " + name + "=" + value); + } else { + Os.setenv(name, value, true); + } + } + private void runCraft() throws Throwable { String[] launchArgs = getMCArgs(); List javaArgList = new ArrayList(); + javaArgList.add(Tools.homeJreDir + "/bin/java"); // javaArgList.add("-Xms512m"); @@ -1001,30 +1015,54 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, javaArgList.add(mVersionInfo.mainClass); javaArgList.addAll(Arrays.asList(launchArgs)); - ShellProcessOperation sp = new ShellProcessOperation(new ShellProcessOperation.OnPrintListener(){ + if (LAUNCH_TYPE == LTYPE_PROCESS) { + mLaunchShell = new ShellProcessOperation(new ShellProcessOperation.OnPrintListener(){ + @Override + public void onPrintLine(String text) { + appendToLog(text, false); + } + }); + mLaunchShell.initInputStream(this); + } + + setEnvironment("JAVA_HOME", Tools.homeJreDir); + setEnvironment("HOME", Tools.MAIN_PATH); + setEnvironment("TMPDIR", getCacheDir().getAbsolutePath()); + setEnvironment("LIBGL_MIPMAP", "3"); + setEnvironment("LD_LIBRARY_PATH", "$JAVA_HOME/lib:$JAVA_HOME/lib/jli:$JAVA_HOME/lib/server"); + + if (LAUNCH_TYPE == LTYPE_PROCESS) { + mLaunchShell.writeToProcess("cd $HOME"); + + mLaunchShell.writeToProcess(javaArgList.toArray(new String[0])); + int exitCode = mLaunchShell.waitFor(); + if (exitCode != 0) { + Tools.showError(this, new ErrnoException("java", exitCode), false); + } + } else { + final FileDescriptor logFile = BinaryExecutor.redirectStdio(); + + new Thread(new Runnable() { @Override - public void onPrintLine(String text) { - appendlnToLog(text, false); + public void run() { + try { + BufferedReader bis = new BufferedReader(new FileReader(logFile)); + String currLine; + while ((currLine = bis.readLine()) != null) { + appendlnToLog(currLine); + } + bis.close(); + } catch (Throwable th) { + appendlnToLog("Can't get log:\n" + Log.getStackTraceString(th)); + } } - }); - sp.initInputStream(this); - - sp.writeToProcess("export JAVA_HOME=" + Tools.homeJreDir); - sp.writeToProcess("export HOME=" + Tools.MAIN_PATH); - sp.writeToProcess("export TMPDIR=" + getCacheDir().getAbsolutePath()); - sp.writeToProcess("export LIBGL_MIPMAP=3"); - - // String libPath = "lib" + (Build.CPU_ABI.contains("64") ? "64" : ""); - sp.writeToProcess("export LD_LIBRARY_PATH=$JAVA_HOME/lib:$JAVA_HOME/lib/jli:$JAVA_HOME/lib/server"); - - sp.writeToProcess("cd $HOME"); - - sp.writeToProcess(javaArgList.toArray(new String[0])); - - int exitCode = sp.waitFor(); - if (exitCode != 0) { - Tools.showError(this, new ErrnoException("java", exitCode), false); + }, "RuntimeLogThread").start(); + + BinaryExecutor.initJavaRuntime(); + BinaryExecutor.chdir(Tools.MAIN_PATH); + + VMLauncher.launchJVM(javaArgList.toArray(new String[0])); } } diff --git a/app/src/main/java/net/kdt/pojavlaunch/ShellProcessOperation.java b/app/src/main/java/net/kdt/pojavlaunch/ShellProcessOperation.java index b34953a13..7733e043b 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/ShellProcessOperation.java +++ b/app/src/main/java/net/kdt/pojavlaunch/ShellProcessOperation.java @@ -73,7 +73,7 @@ public class ShellProcessOperation } } catch (Exception e) { e.printStackTrace(); - listener.onPrintLine(e.getMessage() + "\n"); + listener.onPrintLine("PrintStream error: " + e.getMessage() + "\n"); } } }).start(); diff --git a/app/src/main/jniLibs/arm64-v8a/libbinexecutor.so b/app/src/main/jniLibs/arm64-v8a/libbinexecutor.so new file mode 100644 index 000000000..b73da1c75 Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libbinexecutor.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libbinexecutor.so b/app/src/main/jniLibs/armeabi-v7a/libbinexecutor.so new file mode 100644 index 000000000..dcc4c4e22 Binary files /dev/null and b/app/src/main/jniLibs/armeabi-v7a/libbinexecutor.so differ diff --git a/app/src/main/jniLibs/x86/libbinexecutor.so b/app/src/main/jniLibs/x86/libbinexecutor.so new file mode 100644 index 000000000..9a7480674 Binary files /dev/null and b/app/src/main/jniLibs/x86/libbinexecutor.so differ diff --git a/app/src/main/jniLibs/x86/liblwjgl_opengl.so b/app/src/main/jniLibs/x86/liblwjgl_opengl.so index d3a513e5f..8c84e5e67 100644 Binary files a/app/src/main/jniLibs/x86/liblwjgl_opengl.so and b/app/src/main/jniLibs/x86/liblwjgl_opengl.so differ