mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-15 15:48:26 -04:00
Actual useful multi-runtime
Note: it's not yet exposed in Per-Version-Config and doesn't select automatically for versions that require certain runtimes
This commit is contained in:
parent
7d00a2aee3
commit
4fc232cc16
@ -234,10 +234,10 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
||||
}
|
||||
System.out.println("call to onResumeFragments; E");
|
||||
}
|
||||
public String getFileName(Uri uri) {
|
||||
public static String getFileName(Context ctx, Uri uri) {
|
||||
String result = null;
|
||||
if (uri.getScheme().equals("content")) {
|
||||
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
|
||||
Cursor cursor = ctx.getContentResolver().query(uri, null, null, null, null);
|
||||
try {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||
@ -268,9 +268,11 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
||||
barrier.show();
|
||||
Thread t = new Thread(()->{
|
||||
try {
|
||||
MultiRTUtils.installRuntimeNamed(getContentResolver().openInputStream(uri), getFileName(uri),
|
||||
String name = getFileName(this,uri);
|
||||
MultiRTUtils.installRuntimeNamed(getContentResolver().openInputStream(uri), name,
|
||||
(resid, stuff) -> BaseLauncherActivity.this.runOnUiThread(
|
||||
() -> barrier.setMessage(BaseLauncherActivity.this.getString(resid,stuff))));
|
||||
MultiRTUtils.postPrepare(BaseLauncherActivity.this, name);
|
||||
}catch (IOException e) {
|
||||
Tools.showError(BaseLauncherActivity.this
|
||||
,e);
|
||||
|
@ -20,6 +20,7 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.*;
|
||||
import net.kdt.pojavlaunch.customcontrols.*;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
import net.kdt.pojavlaunch.value.*;
|
||||
@ -128,7 +129,8 @@ public class BaseMainActivity extends LoggableActivity {
|
||||
try {
|
||||
// FIXME: is it safe fot multi thread?
|
||||
GLOBAL_CLIPBOARD = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
|
||||
|
||||
MultiRTUtils.setRuntimeNamed(this,LauncherPreferences.PREF_DEFAULT_RUNTIME);
|
||||
logFile = new File(Tools.DIR_GAME_HOME, "latestlog.txt");
|
||||
logFile.delete();
|
||||
logFile.createNewFile();
|
||||
|
@ -9,6 +9,8 @@ import android.widget.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.prefs.*;
|
||||
import net.kdt.pojavlaunch.utils.*;
|
||||
import org.lwjgl.glfw.*;
|
||||
@ -63,11 +65,13 @@ public class JavaGUILauncherActivity extends LoggableActivity implements View.On
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.install_mod);
|
||||
|
||||
Tools.updateWindowSize(this);
|
||||
|
||||
try {
|
||||
MultiRTUtils.setRuntimeNamed(this,LauncherPreferences.PREF_DEFAULT_RUNTIME);
|
||||
gestureDetector = new GestureDetector(this, new SingleTapConfirm());
|
||||
|
||||
findViewById(R.id.installmod_mouse_pri).setOnTouchListener(this);
|
||||
|
@ -55,7 +55,7 @@ public class PojavApplication extends Application
|
||||
Tools.APP_NAME = getResources().getString(R.string.app_short_name);
|
||||
|
||||
Tools.DIR_DATA = getDir("files", MODE_PRIVATE).getParent();
|
||||
Tools.DIR_HOME_JRE = Tools.DIR_DATA + "/jre_runtime".replace("/data/user/0", "/data/data");
|
||||
//Tools.DIR_HOME_JRE = Tools.DIR_DATA + "/jre_runtime".replace("/data/user/0", "/data/data");
|
||||
Tools.DIR_ACCOUNT_OLD = Tools.DIR_DATA + "/Users";
|
||||
Tools.DIR_ACCOUNT_NEW = Tools.DIR_DATA + "/accounts";
|
||||
// Tools.FILE_ACCOUNT_JSON = getFilesDir().getAbsolutePath() + "/account_profiles.json";
|
||||
|
@ -2,7 +2,10 @@ package net.kdt.pojavlaunch;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -40,6 +43,7 @@ import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
@ -62,6 +66,8 @@ import net.kdt.pojavlaunch.authenticator.mojang.LoginTask;
|
||||
import net.kdt.pojavlaunch.authenticator.mojang.RefreshListener;
|
||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||
import net.kdt.pojavlaunch.customcontrols.CustomControls;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import net.kdt.pojavlaunch.utils.JREUtils;
|
||||
import net.kdt.pojavlaunch.utils.LocaleUtils;
|
||||
@ -278,17 +284,6 @@ public class PojavLoginActivity extends BaseActivity
|
||||
PojavProfile.setCurrentProfile(this, null);
|
||||
}
|
||||
|
||||
private boolean isJavaRuntimeInstalled(AssetManager am) {
|
||||
boolean prefValue = firstLaunchPrefs.getBoolean(PREF_IS_INSTALLED_JAVARUNTIME, false);
|
||||
try {
|
||||
return prefValue && (
|
||||
am.open("components/jre/bin-" + Tools.CURRENT_ARCHITECTURE.split("/")[0] + ".tar.xz") == null ||
|
||||
Tools.read(new FileInputStream(Tools.DIR_HOME_JRE+"/version")).equals(Tools.read(am.open("components/jre/version"))));
|
||||
} catch(IOException e) {
|
||||
Log.e("JVMCtl","failed to read file",e);
|
||||
return prefValue;
|
||||
}
|
||||
}
|
||||
|
||||
private void unpackComponent(AssetManager am, String component) throws IOException {
|
||||
File versionFile = new File(Tools.DIR_GAME_HOME + "/" + component + "/version");
|
||||
@ -368,206 +363,67 @@ public class PojavLoginActivity extends BaseActivity
|
||||
|
||||
unpackComponent(am, "caciocavallo");
|
||||
unpackComponent(am, "lwjgl3");
|
||||
if (!isJavaRuntimeInstalled(am)) {
|
||||
if(!installRuntimeAutomatically(am)) {
|
||||
File jreTarFile = selectJreTarFile();
|
||||
uncompressTarXZ(jreTarFile, new File(Tools.DIR_HOME_JRE));
|
||||
} else {
|
||||
Tools.copyAssetFile(this, "components/jre/version", Tools.DIR_HOME_JRE + "/","version", true);
|
||||
if(!installRuntimeAutomatically(am,MultiRTUtils.getRuntimes().size() > 0)) {
|
||||
MultiRTConfigDialog.openRuntimeSelector(this, MultiRTConfigDialog.MULTIRT_PICK_RUNTIME_STARTUP);
|
||||
synchronized (mLockSelectJRE) {
|
||||
mLockSelectJRE.wait();
|
||||
}
|
||||
firstLaunchPrefs.edit().putBoolean(PREF_IS_INSTALLED_JAVARUNTIME, true).commit();
|
||||
}
|
||||
|
||||
JREUtils.relocateLibPath(this);
|
||||
|
||||
File ftIn = new File(Tools.DIR_HOME_JRE, Tools.DIRNAME_HOME_JRE + "/libfreetype.so.6");
|
||||
File ftOut = new File(Tools.DIR_HOME_JRE, Tools.DIRNAME_HOME_JRE + "/libfreetype.so");
|
||||
if (ftIn.exists() && (!ftOut.exists() || ftIn.length() != ftOut.length())) {
|
||||
ftIn.renameTo(ftOut);
|
||||
}
|
||||
|
||||
// Refresh libraries
|
||||
copyDummyNativeLib("libawt_xawt.so");
|
||||
// copyDummyNativeLib("libfontconfig.so");
|
||||
}
|
||||
catch(Throwable e){
|
||||
Tools.showError(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean installRuntimeAutomatically(AssetManager am) {
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if(requestCode == MultiRTConfigDialog.MULTIRT_PICK_RUNTIME_STARTUP && resultCode == Activity.RESULT_OK) {
|
||||
if (data != null) {
|
||||
final Uri uri = data.getData();
|
||||
Thread t = new Thread(()->{
|
||||
try {
|
||||
MultiRTUtils.installRuntimeNamed(getContentResolver().openInputStream(uri), BaseLauncherActivity.getFileName(this,uri),
|
||||
(resid, stuff) ->PojavLoginActivity.this.runOnUiThread(
|
||||
() -> startupTextView.setText(PojavLoginActivity.this.getString(resid,stuff))));
|
||||
synchronized (mLockSelectJRE) {
|
||||
mLockSelectJRE.notifyAll();
|
||||
}
|
||||
}catch (IOException e) {
|
||||
Tools.showError(PojavLoginActivity.this
|
||||
,e);
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
private boolean installRuntimeAutomatically(AssetManager am, boolean otherRuntimesAvailable) {
|
||||
/* Check if JRE is included */
|
||||
String rt_version = null;
|
||||
String current_rt_version = MultiRTUtils.__internal__readBinpackVersion("Internal");
|
||||
try {
|
||||
am.open("components/jre/version");
|
||||
rt_version = Tools.read(am.open("components/jre/version"));
|
||||
} catch (IOException e) {
|
||||
Log.e("JREAuto", "JRE was not included on this APK.", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
File rtUniversal = new File(Tools.DIR_HOME_JRE+"/universal.tar.xz");
|
||||
File rtPlatformDependent = new File(Tools.DIR_HOME_JRE+"/cust-bin.tar.xz");
|
||||
if(!new File(Tools.DIR_HOME_JRE).exists()) new File(Tools.DIR_HOME_JRE).mkdirs(); else {
|
||||
//SANITY: remove the existing files
|
||||
for (File f : new File(Tools.DIR_HOME_JRE).listFiles()) {
|
||||
if (f.isDirectory()){
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch(IOException e1) {
|
||||
Log.e("JREAuto","da fuq is wrong wit ur device? n2",e1);
|
||||
}
|
||||
} else{
|
||||
f.delete();
|
||||
}
|
||||
if(current_rt_version == null && otherRuntimesAvailable) return true; //Assume user maintains his own runtime
|
||||
if(rt_version == null) return false;
|
||||
if(!current_rt_version.equals(rt_version)) { //If we already have an integrated one installed, check if it's up-to-date
|
||||
try {
|
||||
MultiRTUtils.installRuntimeNamedBinpack(am.open("components/jre/universal.tar.xz"), am.open("components/jre/bin-" + Tools.CURRENT_ARCHITECTURE.split("/")[0] + ".tar.xz"), "Internal", rt_version,
|
||||
(resid, vararg) -> {
|
||||
runOnUiThread(()->{startupTextView.setText(getString(resid,vararg));});
|
||||
});
|
||||
MultiRTUtils.postPrepare(PojavLoginActivity.this,"Internal");
|
||||
return true;
|
||||
}catch (IOException e) {
|
||||
Log.e("JREAuto", "Internal JRE unpack failed", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
InputStream is;
|
||||
FileOutputStream os;
|
||||
try {
|
||||
is = am.open("components/jre/universal.tar.xz");
|
||||
os = new FileOutputStream(rtUniversal);
|
||||
IOUtils.copy(is,os);
|
||||
is.close();
|
||||
os.close();
|
||||
uncompressTarXZ(rtUniversal, new File(Tools.DIR_HOME_JRE));
|
||||
} catch (IOException e){
|
||||
Log.e("JREAuto","Failed to unpack universal. Custom embedded-less build?",e);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
is = am.open("components/jre/bin-" + Tools.CURRENT_ARCHITECTURE.split("/")[0] + ".tar.xz");
|
||||
os = new FileOutputStream(rtPlatformDependent);
|
||||
IOUtils.copy(is, os);
|
||||
is.close();
|
||||
os.close();
|
||||
uncompressTarXZ(rtPlatformDependent, new File(Tools.DIR_HOME_JRE));
|
||||
} catch (IOException e) {
|
||||
// Something's very wrong, or user's using an unsupported arch (MIPS phone? ARMv6 phone?),
|
||||
// in both cases, redirecting to manual install, and removing the universal stuff
|
||||
for (File f : new File(Tools.DIR_HOME_JRE).listFiles()) {
|
||||
if (f.isDirectory()){
|
||||
try {
|
||||
FileUtils.deleteDirectory(f);
|
||||
} catch(IOException e1) {
|
||||
Log.e("JREAuto","da fuq is wrong wit ur device?",e1);
|
||||
}
|
||||
} else{
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private void copyDummyNativeLib(String name) throws Throwable {
|
||||
File fileLib = new File(Tools.DIR_HOME_JRE, Tools.DIRNAME_HOME_JRE + "/" + name);
|
||||
fileLib.delete();
|
||||
FileInputStream is = new FileInputStream(new File(getApplicationInfo().nativeLibraryDir, name));
|
||||
FileOutputStream os = new FileOutputStream(fileLib);
|
||||
IOUtils.copy(is, os);
|
||||
is.close();
|
||||
os.close();
|
||||
}
|
||||
|
||||
private File selectJreTarFile() throws InterruptedException {
|
||||
final StringBuilder selectedFile = new StringBuilder();
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(PojavLoginActivity.this);
|
||||
builder.setTitle(getString(R.string.alerttitle_install_jre, Tools.CURRENT_ARCHITECTURE));
|
||||
builder.setCancelable(false);
|
||||
|
||||
final AlertDialog dialog = builder.create();
|
||||
FileListView flv = new FileListView(dialog, "tar.xz");
|
||||
flv.setFileSelectedListener(new FileSelectedListener(){
|
||||
|
||||
@Override
|
||||
public void onFileSelected(File file, String path) {
|
||||
selectedFile.append(path);
|
||||
dialog.dismiss();
|
||||
|
||||
synchronized (mLockSelectJRE) {
|
||||
mLockSelectJRE.notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
dialog.setView(flv);
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
|
||||
synchronized (mLockSelectJRE) {
|
||||
mLockSelectJRE.wait();
|
||||
}
|
||||
|
||||
return new File(selectedFile.toString());
|
||||
}else return true; // we have at least one runtime, and it's compartible, good to go
|
||||
}
|
||||
|
||||
private void uncompressTarXZ(final File tarFile, final File dest) throws IOException {
|
||||
|
||||
dest.mkdirs();
|
||||
TarArchiveInputStream tarIn = null;
|
||||
|
||||
tarIn = new TarArchiveInputStream(
|
||||
new XZCompressorInputStream(
|
||||
new BufferedInputStream(
|
||||
new FileInputStream(tarFile)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
TarArchiveEntry tarEntry = tarIn.getNextTarEntry();
|
||||
// tarIn is a TarArchiveInputStream
|
||||
while (tarEntry != null) {
|
||||
/*
|
||||
* Unpacking very small files in short time cause
|
||||
* application to ANR or out of memory, so delay
|
||||
* a little if size is below than 20kb (20480 bytes)
|
||||
*/
|
||||
if (tarEntry.getSize() <= 20480) {
|
||||
try {
|
||||
// 40 small files per second
|
||||
Thread.sleep(25);
|
||||
} catch (InterruptedException e) {}
|
||||
}
|
||||
final String tarEntryName = tarEntry.getName();
|
||||
runOnUiThread(new Runnable(){
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
@Override
|
||||
public void run() {
|
||||
startupTextView.setText(getString(R.string.global_unpacking, tarEntryName));
|
||||
}
|
||||
});
|
||||
// publishProgress(null, "Unpacking " + tarEntry.getName());
|
||||
File destPath = new File(dest, tarEntry.getName());
|
||||
if (tarEntry.isSymbolicLink()) {
|
||||
destPath.getParentFile().mkdirs();
|
||||
try {
|
||||
// android.system.Os
|
||||
// Libcore one support all Android versions
|
||||
Os.symlink(tarEntry.getName(), tarEntry.getLinkName());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} else if (tarEntry.isDirectory()) {
|
||||
destPath.mkdirs();
|
||||
destPath.setExecutable(true);
|
||||
} else if (!destPath.exists() || destPath.length() != tarEntry.getSize()) {
|
||||
destPath.getParentFile().mkdirs();
|
||||
destPath.createNewFile();
|
||||
|
||||
FileOutputStream os = new FileOutputStream(destPath);
|
||||
IOUtils.copy(tarIn, os);
|
||||
os.close();
|
||||
|
||||
}
|
||||
tarEntry = tarIn.getNextTarEntry();
|
||||
}
|
||||
tarIn.close();
|
||||
}
|
||||
|
||||
private static boolean mkdirs(String path)
|
||||
{
|
||||
File file = new File(path);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.kdt.pojavlaunch.multirt;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@ -13,7 +14,7 @@ import net.kdt.pojavlaunch.R;
|
||||
|
||||
public class MultiRTConfigDialog {
|
||||
public static final int MULTIRT_PICK_RUNTIME = 2048;
|
||||
public static final int MULTIRT_PICK_RUNTIME_NORETURN = 2049;
|
||||
public static final int MULTIRT_PICK_RUNTIME_STARTUP = 2049;
|
||||
public AlertDialog dialog;
|
||||
public RecyclerView dialogView;
|
||||
public void prepare(BaseLauncherActivity ctx) {
|
||||
@ -29,10 +30,7 @@ public class MultiRTConfigDialog {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
/* Initialte import */
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("application/x-xz");
|
||||
ctx.startActivityForResult(intent,MULTIRT_PICK_RUNTIME);
|
||||
openRuntimeSelector(ctx,MULTIRT_PICK_RUNTIME);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.mcn_exit_call, new DialogInterface.OnClickListener() {
|
||||
@ -46,4 +44,10 @@ public class MultiRTConfigDialog {
|
||||
public void refresh() {
|
||||
dialogView.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
public static void openRuntimeSelector(Activity ctx, int code) {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("application/x-xz");
|
||||
ctx.startActivityForResult(intent,code);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package net.kdt.pojavlaunch.multirt;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
|
||||
import net.kdt.pojavlaunch.PojavLoginActivity;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.utils.JREUtils;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
@ -31,6 +34,7 @@ public class MultiRTUtils {
|
||||
}
|
||||
public String name;
|
||||
public String versionString;
|
||||
public String arch;
|
||||
public int javaVersion;
|
||||
}
|
||||
public static interface ProgressReporterThingy {
|
||||
@ -38,6 +42,7 @@ public class MultiRTUtils {
|
||||
}
|
||||
private static File runtimeFolder = new File(Tools.MULTIRT_HOME);
|
||||
private static final String JAVA_VERSION_str = "JAVA_VERSION=\"";
|
||||
private static final String OS_ARCH_str = "OS_ARCH=\"";
|
||||
public static List<Runtime> getRuntimes() {
|
||||
ArrayList<Runtime> ret = new ArrayList<>();
|
||||
System.out.println("Fetch runtime list");
|
||||
@ -61,6 +66,67 @@ public class MultiRTUtils {
|
||||
tmp.delete();
|
||||
return read(name);
|
||||
}
|
||||
private static void __installRuntimeNamed__NoRM(InputStream runtimeInputStream, File dest, ProgressReporterThingy thingy) throws IOException {
|
||||
File tmp = new File(dest,"temporary");
|
||||
FileOutputStream fos = new FileOutputStream(tmp);
|
||||
thingy.reportStringProgress(R.string.multirt_progress_caching);
|
||||
IOUtils.copy(runtimeInputStream,fos);
|
||||
fos.close();
|
||||
runtimeInputStream.close();
|
||||
uncompressTarXZ(tmp,dest,thingy);
|
||||
tmp.delete();
|
||||
}
|
||||
public static void postPrepare(Context ctx, String name) throws IOException {
|
||||
File dest = new File(runtimeFolder,"/"+name);
|
||||
if(!dest.exists()) return;
|
||||
Runtime r = read(name);
|
||||
String libFolder = "lib";
|
||||
if(new File(dest,libFolder+"/"+r.arch).exists()) libFolder = libFolder+"/"+r.arch;
|
||||
File ftIn = new File(dest, libFolder+ "/libfreetype.so.6");
|
||||
File ftOut = new File(dest, libFolder + "/libfreetype.so");
|
||||
if (ftIn.exists() && (!ftOut.exists() || ftIn.length() != ftOut.length())) {
|
||||
ftIn.renameTo(ftOut);
|
||||
}
|
||||
|
||||
// Refresh libraries
|
||||
copyDummyNativeLib(ctx,"libawt_xawt.so",libFolder);
|
||||
}
|
||||
private static void copyDummyNativeLib(Context ctx, String name, String libFolder) throws IOException {
|
||||
|
||||
File fileLib = new File(MultiRTUtils.runtimeFolder, name+"/"+libFolder + "/" + name);
|
||||
fileLib.delete();
|
||||
FileInputStream is = new FileInputStream(new File(ctx.getApplicationInfo().nativeLibraryDir, name));
|
||||
FileOutputStream os = new FileOutputStream(fileLib);
|
||||
IOUtils.copy(is, os);
|
||||
is.close();
|
||||
os.close();
|
||||
}
|
||||
public static Runtime installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion, ProgressReporterThingy thingy) throws IOException {
|
||||
File dest = new File(runtimeFolder,"/"+name);
|
||||
if(dest.exists()) FileUtils.deleteDirectory(dest);
|
||||
dest.mkdirs();
|
||||
__installRuntimeNamed__NoRM(universalFileInputStream,dest,thingy);
|
||||
__installRuntimeNamed__NoRM(platformBinsInputStream,dest,thingy);
|
||||
File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version");
|
||||
FileOutputStream fos = new FileOutputStream(binpack_verfile);
|
||||
fos.write(binpackVersion.getBytes());
|
||||
fos.close();
|
||||
cache.remove(name); // Force reread
|
||||
return read(name);
|
||||
}
|
||||
public static String __internal__readBinpackVersion(String name) {
|
||||
File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version");
|
||||
try {
|
||||
if (binpack_verfile.exists()) {
|
||||
return Tools.read(binpack_verfile.getAbsolutePath());
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static void removeRuntimeNamed(String name) throws IOException {
|
||||
File dest = new File(runtimeFolder,"/"+name);
|
||||
if(dest.exists()) {
|
||||
@ -68,18 +134,27 @@ public class MultiRTUtils {
|
||||
cache.remove(name);
|
||||
}
|
||||
}
|
||||
public static boolean setRuntimeNamed(Context ctx, String name) throws IOException {
|
||||
File dest = new File(runtimeFolder,"/"+name);
|
||||
if(!dest.exists()) return false;
|
||||
Tools.DIR_HOME_JRE = dest.getAbsolutePath();
|
||||
JREUtils.relocateLibPath(ctx);
|
||||
return true;
|
||||
}
|
||||
private static Runtime read(String name) {
|
||||
if(cache.containsKey(name)) return cache.get(name);
|
||||
Runtime retur;
|
||||
File release = new File(runtimeFolder,"/"+name+"/release");
|
||||
if(!release.exists()) {
|
||||
return null;
|
||||
return new Runtime(name);
|
||||
}
|
||||
try {
|
||||
String content = Tools.read(release.getAbsolutePath());
|
||||
int _JAVA_VERSION_index = content.indexOf(JAVA_VERSION_str);
|
||||
if(_JAVA_VERSION_index != -1) {
|
||||
int _OS_ARCH_index = content.indexOf(OS_ARCH_str);
|
||||
if(_JAVA_VERSION_index != -1 && _OS_ARCH_index != -1) {
|
||||
_JAVA_VERSION_index += JAVA_VERSION_str.length();
|
||||
_OS_ARCH_index += OS_ARCH_str.length();
|
||||
String javaVersion = content.substring(_JAVA_VERSION_index,content.indexOf('"',_JAVA_VERSION_index));
|
||||
String[] javaVersionSplit = javaVersion.split("\\.");
|
||||
int javaVersionInt;
|
||||
@ -89,6 +164,7 @@ public class MultiRTUtils {
|
||||
javaVersionInt = Integer.parseInt(javaVersionSplit[0]);
|
||||
}
|
||||
Runtime r = new Runtime(name);
|
||||
r.arch = content.substring(_OS_ARCH_index,content.indexOf('"',_OS_ARCH_index));
|
||||
r.javaVersion = javaVersionInt;
|
||||
r.versionString = javaVersion;
|
||||
retur = r;
|
||||
|
@ -7,6 +7,7 @@ import android.graphics.Color;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@ -15,6 +16,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@ -34,9 +36,11 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter {
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
final List<MultiRTUtils.Runtime> runtimes = MultiRTUtils.getRuntimes();
|
||||
((RTViewHolder)holder).bindRuntime(runtimes.get(position));
|
||||
((RTViewHolder)holder).bindRuntime(runtimes.get(position),position);
|
||||
}
|
||||
public boolean isDefaultRuntime(MultiRTUtils.Runtime rt) {
|
||||
return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return MultiRTUtils.getRuntimes().size();
|
||||
@ -45,52 +49,69 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter {
|
||||
final TextView javaVersionView;
|
||||
final TextView fullJavaVersionView;
|
||||
final ColorStateList defaultColors;
|
||||
final Button setDefaultButton;
|
||||
final Context ctx;
|
||||
MultiRTUtils.Runtime currentRuntime;
|
||||
int currentPosition;
|
||||
public RTViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
javaVersionView = itemView.findViewById(R.id.multirt_view_java_version);
|
||||
fullJavaVersionView = itemView.findViewById(R.id.multirt_view_java_version_full);
|
||||
itemView.findViewById(R.id.multirt_view_removebtn).setOnClickListener(this);
|
||||
setDefaultButton = itemView.findViewById(R.id.multirt_view_setdefaultbtn);
|
||||
setDefaultButton.setOnClickListener(this);
|
||||
defaultColors = fullJavaVersionView.getTextColors();
|
||||
ctx = itemView.getContext();
|
||||
}
|
||||
public void bindRuntime(MultiRTUtils.Runtime rt) {
|
||||
public void bindRuntime(MultiRTUtils.Runtime rt, int pos) {
|
||||
currentRuntime = rt;
|
||||
currentPosition = pos;
|
||||
if(rt.versionString != null) {
|
||||
javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion));
|
||||
fullJavaVersionView.setText(rt.versionString);
|
||||
fullJavaVersionView.setTextColor(defaultColors);
|
||||
|
||||
setDefaultButton.setVisibility(View.VISIBLE);
|
||||
boolean default_ = isDefaultRuntime(rt);
|
||||
setDefaultButton.setEnabled(!default_);
|
||||
setDefaultButton.setText(default_?R.string.multirt_config_setdefault_already:R.string.multirt_config_setdefault);
|
||||
}else{
|
||||
javaVersionView.setText(rt.name);
|
||||
fullJavaVersionView.setText(R.string.multirt_runtime_corrupt);
|
||||
fullJavaVersionView.setTextColor(Color.RED);
|
||||
setDefaultButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(v.getId() == R.id.multirt_view_removebtn) {
|
||||
if (currentRuntime != null) {
|
||||
final ProgressDialog barrier = new ProgressDialog(ctx);
|
||||
barrier.setMessage(ctx.getString(R.string.global_waiting));
|
||||
barrier.setProgressStyle(barrier.STYLE_SPINNER);
|
||||
barrier.setCancelable(false);
|
||||
barrier.show();
|
||||
Thread t = new Thread(()->{
|
||||
Thread t = new Thread(() -> {
|
||||
try {
|
||||
MultiRTUtils.removeRuntimeNamed(currentRuntime.name);
|
||||
}catch (IOException e) {
|
||||
Tools.showError(itemView.getContext(),e);
|
||||
} catch (IOException e) {
|
||||
Tools.showError(itemView.getContext(), e);
|
||||
}
|
||||
v.post(() ->{
|
||||
v.post(() -> {
|
||||
barrier.dismiss();
|
||||
RTRecyclerViewAdapter.this.notifyDataSetChanged();
|
||||
RTRecyclerViewAdapter.this.notifyItemRemoved(currentPosition);
|
||||
dialog.dialog.show();
|
||||
});
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
}else if(v.getId() == R.id.multirt_view_setdefaultbtn) {
|
||||
if(currentRuntime != null) {
|
||||
LauncherPreferences.PREF_DEFAULT_RUNTIME = currentRuntime.name;
|
||||
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
|
||||
RTRecyclerViewAdapter.this.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package net.kdt.pojavlaunch.prefs;
|
||||
|
||||
import android.content.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
||||
|
||||
public class LauncherPreferences
|
||||
{
|
||||
@ -29,6 +30,7 @@ public class LauncherPreferences
|
||||
public static boolean PREF_DISABLE_GESTURES = false;
|
||||
public static float PREF_MOUSESPEED = 1f;
|
||||
public static int PREF_RAM_ALLOCATION=300;
|
||||
public static String PREF_DEFAULT_RUNTIME;
|
||||
public static void loadPreferences() {
|
||||
PREF_RENDERER = DEFAULT_PREF.getString("renderer", "opengles2");
|
||||
PREF_BUTTONSIZE = DEFAULT_PREF.getInt("buttonscale", 100);
|
||||
@ -108,5 +110,11 @@ public class LauncherPreferences
|
||||
PREF_CUSTOM_JAVA_ARGS.replace(arg, "")).commit();
|
||||
}
|
||||
}
|
||||
if(DEFAULT_PREF.contains("defaultRuntime")) {
|
||||
PREF_DEFAULT_RUNTIME = DEFAULT_PREF.getString("defaultRuntime","");
|
||||
}else{
|
||||
PREF_DEFAULT_RUNTIME = MultiRTUtils.getRuntimes().get(0).name;
|
||||
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
package net.kdt.pojavlaunch.prefs;
|
||||
|
||||
import android.content.*;
|
||||
import androidx.appcompat.app.*;
|
||||
import androidx.preference.*;
|
||||
import android.util.*;
|
||||
import android.widget.*;
|
||||
import java.io.*;
|
||||
import net.kdt.pojavlaunch.*;
|
||||
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import org.apache.commons.io.*;
|
||||
|
||||
public class UninstallJREDialogPreference extends Preference implements DialogInterface.OnClickListener
|
||||
{
|
||||
private AlertDialog mDialog;
|
||||
public UninstallJREDialogPreference(Context ctx) {
|
||||
this(ctx, null);
|
||||
}
|
||||
|
||||
public UninstallJREDialogPreference(Context ctx, AttributeSet attrs) {
|
||||
super(ctx, attrs);
|
||||
setPersistent(false);
|
||||
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
|
||||
dialog.setMessage(R.string.mcl_setting_title_uninstalljre);
|
||||
dialog.setPositiveButton(android.R.string.ok, this);
|
||||
dialog.setNegativeButton(android.R.string.cancel, this);
|
||||
mDialog = dialog.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
super.onClick();
|
||||
mDialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(new File(Tools.DIR_HOME_JRE));
|
||||
|
||||
getContext().getSharedPreferences("pojav_extract", Context.MODE_PRIVATE)
|
||||
.edit().putBoolean(PojavLoginActivity.PREF_IS_INSTALLED_JAVARUNTIME, false).commit();
|
||||
|
||||
Toast.makeText(getContext(), R.string.toast_uninstalljre_done, Toast.LENGTH_SHORT).show();
|
||||
} catch (IOException e) {
|
||||
Tools.showError(getContext(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -168,7 +168,7 @@ public class JREUtils
|
||||
Log.i("jrelog-logcat","Logcat thread started");
|
||||
}
|
||||
|
||||
public static void relocateLibPath(final Context ctx) throws Exception {
|
||||
public static void relocateLibPath(final Context ctx) throws IOException {
|
||||
if (JRE_ARCHITECTURE == null) {
|
||||
JRE_ARCHITECTURE = readJREReleaseProperties().get("OS_ARCH");
|
||||
if (JRE_ARCHITECTURE.startsWith("i") && JRE_ARCHITECTURE.endsWith("86") && Tools.CURRENT_ARCHITECTURE.contains("x86") && !Tools.CURRENT_ARCHITECTURE.contains("64")) {
|
||||
|
@ -39,4 +39,14 @@
|
||||
app:layout_constraintTop_toTopOf="@+id/multirt_view_java_version"
|
||||
app:srcCompat="@drawable/ic_remove" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/multirt_view_setdefaultbtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/multirt_config_setdefault"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/multirt_view_removebtn"
|
||||
app:layout_constraintTop_toTopOf="@+id/multirt_view_removebtn" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -219,4 +219,6 @@
|
||||
<string name="multirt_title">Runtime Manager</string>
|
||||
<string name="multirt_subtitle">Manage installed Java VMs</string>
|
||||
<string name="multirt_progress_caching">Caching...</string>
|
||||
<string name="multirt_config_setdefault">Set default</string>
|
||||
<string name="multirt_config_setdefault_already">Default</string>
|
||||
</resources>
|
||||
|
@ -6,10 +6,6 @@
|
||||
<androidx.preference.PreferenceCategory
|
||||
android:title="@string/mcl_setting_category_general">
|
||||
|
||||
<net.kdt.pojavlaunch.prefs.UninstallJREDialogPreference
|
||||
android:summary="@string/mcl_setting_subtitle_uninstalljre"
|
||||
android:title="@string/mcl_setting_title_uninstalljre"
|
||||
app2:icon="@drawable/rm_jre" />
|
||||
<net.kdt.pojavlaunch.prefs.RuntimeManagerPreference
|
||||
android:summary="@string/multirt_subtitle"
|
||||
android:title="@string/multirt_title"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user