diff --git a/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java b/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java index 78497c503..6f4efac33 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java +++ b/app/src/main/java/net/kdt/pojavlaunch/InstallModActivity.java @@ -2,79 +2,118 @@ package net.kdt.pojavlaunch; import android.graphics.*; import android.os.*; -import android.support.v7.app.*; import android.view.*; +import android.widget.*; import com.oracle.dalvik.*; import java.io.*; -import java.util.*; import java.lang.reflect.*; +import java.util.*; -public class InstallModActivity extends AppCompatActivity +public class InstallModActivity extends LoggableActivity { private TextureView mTextureView; + private LinearLayout contentLog; + private TextView textLog; + private ScrollView contentScroll; + private ToggleButton toggleLog; + + private File logFile; + private PrintStream logStream; + + private boolean isLogAllow; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.install_mod); - - final File modFile = (File) getIntent().getExtras().getSerializable("modFile"); - - mTextureView = findViewById(R.id.installmod_surfaceview); - mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener(){ + + try { + logFile = new File(Tools.MAIN_PATH, "latestlog.txt"); + logFile.delete(); + logFile.createNewFile(); + logStream = new PrintStream(logFile.getAbsolutePath()); + this.contentLog = (LinearLayout) findViewById(R.id.content_log_layout); + this.contentScroll = (ScrollView) findViewById(R.id.content_log_scroll); + this.textLog = (TextView) contentScroll.getChildAt(0); + this.toggleLog = (ToggleButton) findViewById(R.id.content_log_toggle_log); + this.toggleLog.setChecked(false); + // this.textLogBehindGL = (TextView) findViewById(R.id.main_log_behind_GL); + // this.textLogBehindGL.setTypeface(Typeface.MONOSPACE); + this.textLog.setTypeface(Typeface.MONOSPACE); + this.toggleLog.setOnCheckedChangeListener(new ToggleButton.OnCheckedChangeListener(){ + @Override + public void onCheckedChanged(CompoundButton button, boolean isChecked) { + isLogAllow = isChecked; + appendToLog(""); + } + }); + JREUtils.redirectAndPrintJRELog(this); + + final File modFile = (File) getIntent().getExtras().getSerializable("modFile"); - @Override - public void onSurfaceTextureAvailable(SurfaceTexture tex, int w, int h) { - try { - Surface surface = new Surface(tex); - Field field = surface.getClass().getDeclaredField("mNativeObject"); - field.setAccessible(true); - JREUtils.setupBridgeSurfaceAWT((long) field.get(surface)); - } catch (Throwable th) { - Tools.showError(InstallModActivity.this, th, true); - } - - new Thread(new Runnable(){ - @Override - public void run() { - launchJavaRuntime(modFile); - // finish(); - } - }).start(); - } + mTextureView = findViewById(R.id.installmod_surfaceview); + mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener(){ - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture tex) { - return false; - } + @Override + public void onSurfaceTextureAvailable(SurfaceTexture tex, int w, int h) { + try { + Surface surface = new Surface(tex); + Field field = surface.getClass().getDeclaredField("mNativeObject"); + field.setAccessible(true); + JREUtils.setupBridgeSurfaceAWT((long) field.get(surface)); + } catch (Throwable th) { + Tools.showError(InstallModActivity.this, th, true); + } - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture tex, int w, int h) { - - } + new Thread(new Runnable(){ + @Override + public void run() { + launchJavaRuntime(modFile); + // finish(); + } + }).start(); + } - @Override - public void onSurfaceTextureUpdated(SurfaceTexture tex) { - - } - }); + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture tex) { + return false; + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture tex, int w, int h) { + + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture tex) { + + } + }); + } catch (Throwable th) { + Tools.showError(this, th, true); + } } public void forceClose(View v) { MainActivity.dialogForceClose(this); } - + + public void openLogOutput(View v) { + contentLog.setVisibility(View.VISIBLE); + } + + public void closeLogOutput(View view) { + contentLog.setVisibility(View.GONE); + // mIsResuming = true; + } + private void launchJavaRuntime(File modFile) { try { List javaArgList = new ArrayList(); javaArgList.add(Tools.homeJreDir + "/bin/java"); - // javaArgList.add("-Xms512m"); - javaArgList.add("-Xmx512m"); - - javaArgList.add("-Djava.home=" + Tools.homeJreDir); - javaArgList.add("-Djava.io.tmpdir=" + getCacheDir().getAbsolutePath()); - javaArgList.add("-Dos.name=Linux"); + Tools.getJavaArgs(this, javaArgList); File cacioAwtLibPath = new File(Tools.MAIN_PATH, "cacioawtlib"); if (cacioAwtLibPath.exists()) { @@ -107,4 +146,17 @@ public class InstallModActivity extends AppCompatActivity Tools.showError(this, th, true); } } + + @Override + public void appendToLog(final String text, boolean checkAllow) { + logStream.print(text); + if (checkAllow && !isLogAllow) return; + textLog.post(new Runnable(){ + @Override + public void run() { + textLog.append(text); + contentScroll.fullScroll(ScrollView.FOCUS_DOWN); + } + }); + } } diff --git a/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java b/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java index c393e9518..94d3244b3 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java +++ b/app/src/main/java/net/kdt/pojavlaunch/JREUtils.java @@ -1,8 +1,9 @@ package net.kdt.pojavlaunch; -import android.system.*; -import java.io.*; import android.content.*; +import android.system.*; +import android.util.*; +import java.io.*; import net.kdt.pojavlaunch.prefs.*; public class JREUtils @@ -31,7 +32,42 @@ public class JREUtils dlopen(nativeLibDir + "/libgl04es.so"); } } - public static native void redirectLogcat(); + + public static void redirectAndPrintJRELog(LoggableActivity act) { + JREUtils.redirectLogcat(); + Log.v("jrelog","Log starts here"); + Thread t = new Thread(() -> { + try { + Log.i("jrelog-logcat","Clearing logcat"); + new ProcessBuilder().command("logcat", "-c").redirectErrorStream(true).start(); + Log.i("jrelog-logcat","Starting logcat"); + Process p = new ProcessBuilder().command("logcat", /* "-G", "1mb", */ "-v", "brief", "*:S").redirectErrorStream(true).start(); + + // idk which better, but 512bytes may make a bug that printf(\n) in a single line + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line; + while ((line = reader.readLine()) != null) { + act.appendlnToLog(line); + } + + /* + byte[] buf = new byte[512]; + int len; + while ((len = p.getInputStream().read(buf)) != -1) { + appendToLog(new String(buf, 0, len)); + } + */ + } catch (IOException e) { + Log.e("jrelog-logcat", "IOException on logging thread"); + e.printStackTrace(); + + act.appendlnToLog("IOException on logging thread:\n" + Log.getStackTraceString(e)); + } + }); + t.start(); + Log.i("jrelog-logcat","Logcat thread started"); + } + public static void setJavaEnvironment(Context ctx) throws IOException, ErrnoException { nativeLibDir = ctx.getApplicationInfo().nativeLibraryDir; String libName = System.getProperty("os.arch").contains("64") ? "lib64" : "lib"; @@ -77,6 +113,7 @@ public class JREUtils public static native int chdir(String path); public static native boolean dlopen(String libPath); + public static native void redirectLogcat(); public static native void setLdLibraryPath(String ldLibraryPath); public static native void setupBridgeWindow(Object surface); diff --git a/app/src/main/java/net/kdt/pojavlaunch/LoggableActivity.java b/app/src/main/java/net/kdt/pojavlaunch/LoggableActivity.java new file mode 100644 index 000000000..58911748e --- /dev/null +++ b/app/src/main/java/net/kdt/pojavlaunch/LoggableActivity.java @@ -0,0 +1,20 @@ +package net.kdt.pojavlaunch; + +import android.support.v7.app.*; + +public abstract class LoggableActivity extends AppCompatActivity + { + public void appendToLog(String text) { + appendToLog(text, true); + } + + public void appendlnToLog(String text) { + appendlnToLog(text, true); + } + + public void appendlnToLog(String text, boolean checkAllow) { + appendToLog(text + "\n", checkAllow); + } + + public abstract void appendToLog(final String text, boolean checkAllow); +} diff --git a/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java index a8f790052..799fa0508 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -24,7 +24,7 @@ import org.lwjgl.glfw.*; import android.app.AlertDialog; import java.lang.Process; -public class MainActivity extends AppCompatActivity implements OnTouchListener, OnClickListener +public class MainActivity extends LoggableActivity implements OnTouchListener, OnClickListener { public static final String initText = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "; @@ -85,7 +85,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, private NavigationView navDrawer; private LinearLayout contentLog; - private TextView textLog, textLogBehindGL; + private TextView textLog; private ScrollView contentScroll; private ToggleButton toggleLog; private GestureDetector gestureDetector; @@ -103,7 +103,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, private Button[] controlButtons; - private File currLogFile, logFile; + private File logFile; private PrintStream logStream; /* @@ -238,8 +238,8 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, this.textLog = (TextView) contentScroll.getChildAt(0); this.toggleLog = (ToggleButton) findViewById(R.id.content_log_toggle_log); this.toggleLog.setChecked(false); - this.textLogBehindGL = (TextView) findViewById(R.id.main_log_behind_GL); - this.textLogBehindGL.setTypeface(Typeface.MONOSPACE); + // this.textLogBehindGL = (TextView) findViewById(R.id.main_log_behind_GL); + // this.textLogBehindGL.setTypeface(Typeface.MONOSPACE); this.textLog.setTypeface(Typeface.MONOSPACE); this.toggleLog.setOnCheckedChangeListener(new ToggleButton.OnCheckedChangeListener(){ @@ -247,10 +247,6 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, @Override public void onCheckedChanged(CompoundButton button, boolean isChecked) { - try { - if (isChecked) Tools.write(currLogFile.getAbsolutePath(), ""); - } catch (Exception e) {} - isLogAllow = isChecked; appendToLog(""); } @@ -842,7 +838,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, return Build.VERSION.SDK_INT >= 26; } - private FileObserver mLogObserver; + // private FileObserver mLogObserver; private void runCraft() throws Throwable { /* Old logger if (Tools.LAUNCH_TYPE != Tools.LTYPE_PROCESS) { @@ -865,25 +861,18 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, mLogObserver.startWatching(); } */ - JREUtils.redirectLogcat(); - Log.v("jrelog","Log starts here"); - Thread t = new Thread(() -> { - try { - Log.i("jrelog-logcat","Clearing logcat"); - new ProcessBuilder().command("logcat", "-c").redirectErrorStream(true).start(); - Log.i("jrelog-logcat","Starting logcat"); - Process p = new ProcessBuilder().command("logcat", /* "-G", "1mb", */ "-v", "brief", "*:S").redirectErrorStream(true).start(); - byte[] buf = new byte[512]; - int len; - while ((len = p.getInputStream().read(buf)) != -1) { - appendToLog(new String(buf, 0, len)); - } - }catch (IOException e) { - e.printStackTrace(); - } - }); - t.start(); - Log.i("jrelog-logcat","Logcat thread started"); + + appendlnToLog("--------- beggining with launcher debug"); + File lwjgl3dir = new File(Tools.MAIN_PATH, "lwjgl3"); + if (!lwjgl3dir.exists() || lwjgl3dir.isFile() || lwjgl3dir.length() == 0) { + appendlnToLog("Error: LWJGL3 is not installed!"); + Tools.showError(this, new Throwable("LWJGL3 is not installed!"), true); + return; + } else { + appendlnToLog("Info: LWJGL3 directory size: " + lwjgl3dir.length()); + } + + JREUtils.redirectAndPrintJRELog(this); Tools.launchMinecraft(this, mProfile, mVersionInfo); } @@ -942,19 +931,9 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener, WindowAnimation.fadeOut(contentCanvas, 500); } */ - private void appendToLog(String text) { - appendToLog(text, true); - } - - private void appendlnToLog(String text) { - appendlnToLog(text, true); - } - - private void appendlnToLog(String text, boolean checkAllow) { - appendToLog(text + "\n", checkAllow); - } - - private void appendToLog(final String text, boolean checkAllow) { + + @Override + public void appendToLog(final String text, boolean checkAllow) { logStream.print(text); if (checkAllow && !isLogAllow) return; textLog.post(new Runnable(){ diff --git a/app/src/main/java/net/kdt/pojavlaunch/Tools.java b/app/src/main/java/net/kdt/pojavlaunch/Tools.java index de2d7bdd2..c7a0ddcde 100644 --- a/app/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -81,35 +81,6 @@ public final class Tools */ javaArgList.add(Tools.homeJreDir + "/bin/java"); - List overrideableArgList = new ArrayList(); - - overrideableArgList.add("-Djava.home=" + Tools.homeJreDir); - overrideableArgList.add("-Djava.io.tmpdir=" + ctx.getCacheDir().getAbsolutePath()); - overrideableArgList.add("-Dos.name=Linux"); - - // javaArgList.add("-Dorg.lwjgl.libname=liblwjgl3.so"); - // javaArgList.add("-Dorg.lwjgl.system.jemalloc.libname=libjemalloc.so"); - overrideableArgList.add("-Dorg.lwjgl.opengl.libname=libgl04es.so"); - // javaArgList.add("-Dorg.lwjgl.opengl.libname=libRegal.so"); - - // Enable LWJGL3 debug - overrideableArgList.add("-Dorg.lwjgl.util.Debug=true"); - // overrideableArgList.add("-Dorg.lwjgl.util.DebugFunctions=true"); - overrideableArgList.add("-Dorg.lwjgl.util.DebugLoader=true"); - - // GLFW Stub width height - overrideableArgList.add("-Dglfwstub.windowWidth=" + CallbackBridge.windowWidth); - overrideableArgList.add("-Dglfwstub.windowHeight=" + CallbackBridge.windowHeight); - - overrideableArgList.add("-Dglfwstub.initEgl=false"); - - if (versionInfo.arguments != null) { - // Minecraft 1.13+ - - overrideableArgList.add("-Dminecraft.launcher.brand=" + Tools.APP_NAME); - overrideableArgList.add("-Dminecraft.launcher.version=" + ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), 0).versionName); - } - String launchClassPath = generateLaunchClassPath(profile.getVersion()); System.out.println("Java Classpath: " + launchClassPath); if (LAUNCH_TYPE == LTYPE_CREATEJAVAVM) { @@ -128,21 +99,8 @@ public final class Tools javaArgList.add("-Dglfwstub.eglSurfaceDraw=" + Tools.getEGLAddress("Surface", AndroidContextImplementation.draw)); } */ - // Override args - // TODO fix duplicate args - for (String argOverride : LauncherPreferences.PREF_CUSTOM_JAVA_ARGS.split(" ")) { - for (int i = 0; i < overrideableArgList.size(); i++) { - String arg = overrideableArgList.get(i); - if (arg.startsWith("-D") && argOverride.startsWith(arg.substring(0, arg.indexOf('=') + 1))) { - overrideableArgList.set(i, argOverride); - break; - } else if (i+1 == overrideableArgList.size()) { - javaArgList.add(argOverride); - } - } - } - javaArgList.addAll(overrideableArgList); + getJavaArgs(ctx, javaArgList); javaArgList.add("-cp"); javaArgList.add(launchClassPath); @@ -218,7 +176,49 @@ public final class Tools } }); } - + + public static void getJavaArgs(Context ctx, List javaArgList) { + List overrideableArgList = new ArrayList(); + + overrideableArgList.add("-Djava.home=" + Tools.homeJreDir); + overrideableArgList.add("-Djava.io.tmpdir=" + ctx.getCacheDir().getAbsolutePath()); + + // Should be compatible? + overrideableArgList.add("-Dos.name=Android"); + overrideableArgList.add("-Dos.version=" + Build.VERSION.SDK); + + // javaArgList.add("-Dorg.lwjgl.libname=liblwjgl3.so"); + // javaArgList.add("-Dorg.lwjgl.system.jemalloc.libname=libjemalloc.so"); + overrideableArgList.add("-Dorg.lwjgl.opengl.libname=libgl04es.so"); + // javaArgList.add("-Dorg.lwjgl.opengl.libname=libRegal.so"); + + // Enable LWJGL3 debug + overrideableArgList.add("-Dorg.lwjgl.util.Debug=true"); + // overrideableArgList.add("-Dorg.lwjgl.util.DebugFunctions=true"); + overrideableArgList.add("-Dorg.lwjgl.util.DebugLoader=true"); + + // GLFW Stub width height + overrideableArgList.add("-Dglfwstub.windowWidth=" + CallbackBridge.windowWidth); + overrideableArgList.add("-Dglfwstub.windowHeight=" + CallbackBridge.windowHeight); + + overrideableArgList.add("-Dglfwstub.initEgl=false"); + + // Override args + for (String argOverride : LauncherPreferences.PREF_CUSTOM_JAVA_ARGS.split(" ")) { + for (int i = 0; i < overrideableArgList.size(); i++) { + String arg = overrideableArgList.get(i); + if (arg.startsWith("-D") && argOverride.startsWith(arg.substring(0, arg.indexOf('=') + 1))) { + overrideableArgList.set(i, argOverride); + break; + } else if (i+1 == overrideableArgList.size()) { + javaArgList.add(argOverride); + } + } + } + + javaArgList.addAll(overrideableArgList); + } + public static String[] getMinecraftArgs(MCProfile.Builder profile, JMinecraftVersionList.Version versionInfo) { String username = profile.getUsername(); diff --git a/app/src/main/res/layout/install_mod.xml b/app/src/main/res/layout/install_mod.xml index b2c86494c..c8527e7c2 100644 --- a/app/src/main/res/layout/install_mod.xml +++ b/app/src/main/res/layout/install_mod.xml @@ -1,21 +1,89 @@ - - + android:layout_width="match_parent"> -