Refactor multiRT

This commit is contained in:
SerpentSpirale 2022-02-26 00:32:46 +01:00 committed by ArtDev
parent a78e66f793
commit 9b35bc084f
10 changed files with 278 additions and 255 deletions

View File

@ -4,20 +4,15 @@ import static net.kdt.pojavlaunch.Tools.getFileName;
import android.app.*; import android.app.*;
import android.content.*; import android.content.*;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.provider.OpenableColumns;
import android.text.*;
import android.text.method.*;
import android.view.*; import android.view.*;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import android.widget.*; import android.widget.*;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.*;
import com.kdt.pickafile.*;
import java.io.*; import java.io.*;
import net.kdt.pojavlaunch.fragments.*;
import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog;
import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.prefs.*;
@ -65,7 +60,7 @@ public abstract class BaseLauncherActivity extends BaseActivity {
public static final int RUN_MOD_INSTALLER = 2050; public static final int RUN_MOD_INSTALLER = 2050;
private void installMod(boolean customJavaArgs) { private void installMod(boolean customJavaArgs) {
if (MultiRTUtils.getExactJREName(8) == null) { if (MultiRTUtils.getExactJreName(8) == null) {
Toast.makeText(this, R.string.multirt_nojava8rt, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.multirt_nojava8rt, Toast.LENGTH_LONG).show();
return; return;
} }
@ -190,7 +185,7 @@ public abstract class BaseLauncherActivity extends BaseActivity {
BaseLauncherActivity.this.runOnUiThread(() -> { BaseLauncherActivity.this.runOnUiThread(() -> {
barrier.dismiss(); barrier.dismiss();
mRuntimeConfigDialog.refresh(); mRuntimeConfigDialog.refresh();
mRuntimeConfigDialog.dialog.show(); mRuntimeConfigDialog.mDialog.show();
}); });
}); });
t.start(); t.start();

View File

@ -1,6 +1,5 @@
package net.kdt.pojavlaunch; package net.kdt.pojavlaunch;
import android.graphics.*;
import android.os.*; import android.os.*;
import android.util.*; import android.util.*;
import android.view.*; import android.view.*;
@ -71,7 +70,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
if (JREUtils.jreReleaseList.get("JAVA_VERSION").equals("1.8.0")) { if (JREUtils.jreReleaseList.get("JAVA_VERSION").equals("1.8.0")) {
MultiRTUtils.setRuntimeNamed(this,LauncherPreferences.PREF_DEFAULT_RUNTIME); MultiRTUtils.setRuntimeNamed(this,LauncherPreferences.PREF_DEFAULT_RUNTIME);
} else { } else {
MultiRTUtils.setRuntimeNamed(this,MultiRTUtils.getExactJREName(8)); MultiRTUtils.setRuntimeNamed(this,MultiRTUtils.getExactJreName(8));
JREUtils.jreReleaseList = JREUtils.readJREReleaseProperties(); JREUtils.jreReleaseList = JREUtils.readJREReleaseProperties();
} }

View File

@ -14,31 +14,33 @@ import net.kdt.pojavlaunch.R;
public class MultiRTConfigDialog { public class MultiRTConfigDialog {
public static final int MULTIRT_PICK_RUNTIME = 2048; public static final int MULTIRT_PICK_RUNTIME = 2048;
public static final int MULTIRT_PICK_RUNTIME_STARTUP = 2049; public static final int MULTIRT_PICK_RUNTIME_STARTUP = 2049;
public AlertDialog dialog; public AlertDialog mDialog;
public RecyclerView dialogView; public RecyclerView mDialogView;
public void prepare(BaseLauncherActivity ctx) {
AlertDialog.Builder builder = new AlertDialog.Builder(ctx); public void prepare(BaseLauncherActivity activity) {
mDialogView = new RecyclerView(activity);
mDialogView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false));
mDialogView.setAdapter(new RTRecyclerViewAdapter(this));
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(R.string.multirt_config_title); builder.setTitle(R.string.multirt_config_title);
dialogView = new RecyclerView(ctx); builder.setView(mDialogView);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx); builder.setPositiveButton(R.string.multirt_config_add, (dialog, which) -> openRuntimeSelector(activity,MULTIRT_PICK_RUNTIME));
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
dialogView.setLayoutManager(linearLayoutManager);
dialogView.setAdapter(new RTRecyclerViewAdapter(this));
builder.setView(dialogView);
builder.setPositiveButton(R.string.multirt_config_add, (dialog, which) -> openRuntimeSelector(ctx,MULTIRT_PICK_RUNTIME));
builder.setNegativeButton(R.string.mcn_exit_call, (dialog, which) -> dialog.cancel()); builder.setNegativeButton(R.string.mcn_exit_call, (dialog, which) -> dialog.cancel());
dialog = builder.create(); mDialog = builder.create();
} }
public void refresh() { public void refresh() {
RecyclerView.Adapter adapter = dialogView.getAdapter(); RecyclerView.Adapter adapter = mDialogView.getAdapter();
if(adapter != null)dialogView.getAdapter().notifyDataSetChanged(); if(adapter != null) mDialogView.getAdapter().notifyDataSetChanged();
} }
public static void openRuntimeSelector(Activity ctx, int code) {
public static void openRuntimeSelector(Activity activity, int code) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("xz"); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("xz");
if(mimeType == null) mimeType = "*/*"; if(mimeType == null) mimeType = "*/*";
intent.setType(mimeType); intent.setType(mimeType);
ctx.startActivityForResult(intent,code); activity.startActivityForResult(intent,code);
} }
} }

View File

@ -2,6 +2,7 @@ package net.kdt.pojavlaunch.multirt;
import android.content.Context; import android.content.Context;
import android.system.Os; import android.system.Os;
import android.util.Log;
import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools; import net.kdt.pojavlaunch.Tools;
@ -22,135 +23,102 @@ import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Objects;
public class MultiRTUtils { public class MultiRTUtils {
public static HashMap<String,Runtime> cache = new HashMap<>(); public interface RuntimeProgressReporter {
public static class Runtime { void reportStringProgress(int resId, Object ... stuff);
public Runtime(String name) { }
this.name = name;
} private static final HashMap<String,Runtime> sCache = new HashMap<>();
public String name;
public String versionString; private static final File RUNTIME_FOLDER = new File(Tools.MULTIRT_HOME);
public String arch; private static final String JAVA_VERSION_STR = "JAVA_VERSION=\"";
public int javaVersion; private static final String OS_ARCH_STR = "OS_ARCH=\"";
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Runtime runtime = (Runtime) o;
return name.equals(runtime.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static interface ProgressReporterThingy {
void reportStringProgress(int resid, Object ... stuff);
}
private static final 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() { public static List<Runtime> getRuntimes() {
if(!runtimeFolder.exists()) runtimeFolder.mkdirs(); if(!RUNTIME_FOLDER.exists()) RUNTIME_FOLDER.mkdirs();
ArrayList<Runtime> ret = new ArrayList<>();
ArrayList<Runtime> runtimes = new ArrayList<>();
System.out.println("Fetch runtime list"); System.out.println("Fetch runtime list");
for(File f : runtimeFolder.listFiles()) { for(File f : RUNTIME_FOLDER.listFiles()) {
ret.add(read(f.getName())); runtimes.add(read(f.getName()));
} }
return ret; return runtimes;
} }
public static String getExactJREName(int majorVersion) {
public static String getExactJreName(int majorVersion) {
List<Runtime> runtimes = getRuntimes(); List<Runtime> runtimes = getRuntimes();
for(Runtime r : runtimes) { for(Runtime r : runtimes)
if(r.javaVersion == majorVersion) { if(r.javaVersion == majorVersion)return r.name;
return r.name;
}
}
return null; return null;
} }
public static String getNearestJREName(int majorVersion) {
public static String getNearestJreName(int majorVersion) {
List<Runtime> runtimes = getRuntimes(); List<Runtime> runtimes = getRuntimes();
int diff_factor = Integer.MAX_VALUE; int diff_factor = Integer.MAX_VALUE;
String result = null; String result = null;
for(Runtime r : runtimes) { for(Runtime r : runtimes) {
if(r.javaVersion >= majorVersion) { // lower - not useful if(r.javaVersion < majorVersion) continue; // lower - not useful
int currentFactor = r.javaVersion - majorVersion;
if(diff_factor > currentFactor) { int currentFactor = r.javaVersion - majorVersion;
result = r.name; if(diff_factor > currentFactor) {
diff_factor = currentFactor; result = r.name;
} diff_factor = currentFactor;
} }
} }
return result; return result;
} }
public static void installRuntimeNamed(InputStream runtimeInputStream, String name, ProgressReporterThingy thingy) throws IOException {
File dest = new File(runtimeFolder,"/"+name); public static void installRuntimeNamed(InputStream runtimeInputStream, String name, RuntimeProgressReporter progressReporter) throws IOException {
File dest = new File(RUNTIME_FOLDER,"/"+name);
File tmp = new File(dest,"temporary"); File tmp = new File(dest,"temporary");
if(dest.exists()) FileUtils.deleteDirectory(dest); if(dest.exists()) FileUtils.deleteDirectory(dest);
dest.mkdirs(); dest.mkdirs();
FileOutputStream fos = new FileOutputStream(tmp); FileOutputStream fos = new FileOutputStream(tmp);
thingy.reportStringProgress(R.string.multirt_progress_caching); progressReporter.reportStringProgress(R.string.multirt_progress_caching);
IOUtils.copy(runtimeInputStream,fos); IOUtils.copy(runtimeInputStream,fos);
fos.close(); fos.close();
runtimeInputStream.close(); runtimeInputStream.close();
uncompressTarXZ(tmp,dest,thingy); uncompressTarXZ(tmp,dest,progressReporter);
tmp.delete(); tmp.delete();
read(name); 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 { public static void postPrepare(Context ctx, String name) throws IOException {
File dest = new File(runtimeFolder,"/"+name); File dest = new File(RUNTIME_FOLDER,"/" + name);
if(!dest.exists()) return; if(!dest.exists()) return;
Runtime r = read(name); Runtime runtime = read(name);
String libFolder = "lib"; String libFolder = "lib";
if(new File(dest,libFolder+"/"+r.arch).exists()) libFolder = libFolder+"/"+r.arch; if(new File(dest,libFolder + "/" + runtime.arch).exists()) libFolder = libFolder + "/" + runtime.arch;
File ftIn = new File(dest, libFolder+ "/libfreetype.so.6"); File ftIn = new File(dest, libFolder + "/libfreetype.so.6");
File ftOut = new File(dest, libFolder + "/libfreetype.so"); File ftOut = new File(dest, libFolder + "/libfreetype.so");
if (ftIn.exists() && (!ftOut.exists() || ftIn.length() != ftOut.length())) { if (ftIn.exists() && (!ftOut.exists() || ftIn.length() != ftOut.length())) {
ftIn.renameTo(ftOut); ftIn.renameTo(ftOut);
} }
// Refresh libraries // Refresh libraries
copyDummyNativeLib(ctx,"libawt_xawt.so",dest,libFolder); copyDummyNativeLib(ctx,"libawt_xawt.so", dest, libFolder);
} }
private static void copyDummyNativeLib(Context ctx, String name, File dest, String libFolder) throws IOException {
File fileLib = new File(dest, "/"+libFolder + "/" + name); public static Runtime installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion, RuntimeProgressReporter thingy) throws IOException {
fileLib.delete(); File dest = new File(RUNTIME_FOLDER,"/"+name);
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); if(dest.exists()) FileUtils.deleteDirectory(dest);
dest.mkdirs(); dest.mkdirs();
__installRuntimeNamed__NoRM(universalFileInputStream,dest,thingy); installRuntimeNamedNoRemove(universalFileInputStream,dest,thingy);
__installRuntimeNamed__NoRM(platformBinsInputStream,dest,thingy); installRuntimeNamedNoRemove(platformBinsInputStream,dest,thingy);
File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version"); File binpack_verfile = new File(RUNTIME_FOLDER,"/"+name+"/pojav_version");
FileOutputStream fos = new FileOutputStream(binpack_verfile); FileOutputStream fos = new FileOutputStream(binpack_verfile);
fos.write(binpackVersion.getBytes()); fos.write(binpackVersion.getBytes());
fos.close(); fos.close();
cache.remove(name); // Force reread sCache.remove(name); // Force reread
return read(name); return read(name);
} }
public static String __internal__readBinpackVersion(String name) { public static String __internal__readBinpackVersion(String name) {
File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version"); File binpack_verfile = new File(RUNTIME_FOLDER,"/"+name+"/pojav_version");
try { try {
if (binpack_verfile.exists()) { if (binpack_verfile.exists()) {
return Tools.read(binpack_verfile.getAbsolutePath()); return Tools.read(binpack_verfile.getAbsolutePath());
@ -162,38 +130,42 @@ public class MultiRTUtils {
return null; return null;
} }
} }
public static void removeRuntimeNamed(String name) throws IOException { public static void removeRuntimeNamed(String name) throws IOException {
File dest = new File(runtimeFolder,"/"+name); File dest = new File(RUNTIME_FOLDER,"/"+name);
if(dest.exists()) { if(dest.exists()) {
FileUtils.deleteDirectory(dest); FileUtils.deleteDirectory(dest);
cache.remove(name); sCache.remove(name);
} }
} }
public static void setRuntimeNamed(Context ctx, String name) throws IOException { public static void setRuntimeNamed(Context ctx, String name) throws IOException {
File dest = new File(runtimeFolder,"/"+name); File dest = new File(RUNTIME_FOLDER,"/"+name);
if((!dest.exists()) || MultiRTUtils.forceReread(name).versionString == null) throw new RuntimeException("Selected runtime is broken!"); if((!dest.exists()) || MultiRTUtils.forceReread(name).versionString == null) throw new RuntimeException("Selected runtime is broken!");
Tools.DIR_HOME_JRE = dest.getAbsolutePath(); Tools.DIR_HOME_JRE = dest.getAbsolutePath();
JREUtils.relocateLibPath(ctx); JREUtils.relocateLibPath(ctx);
} }
public static Runtime forceReread(String name) { public static Runtime forceReread(String name) {
cache.remove(name); sCache.remove(name);
return read(name); return read(name);
} }
public static Runtime read(String name) { public static Runtime read(String name) {
if(cache.containsKey(name)) return cache.get(name); if(sCache.containsKey(name)) return sCache.get(name);
Runtime retur; Runtime returnRuntime;
File release = new File(runtimeFolder,"/"+name+"/release"); File release = new File(RUNTIME_FOLDER,"/"+name+"/release");
if(!release.exists()) { if(!release.exists()) {
return new Runtime(name); return new Runtime(name);
} }
try { try {
String content = Tools.read(release.getAbsolutePath()); String content = Tools.read(release.getAbsolutePath());
int _JAVA_VERSION_index = content.indexOf(JAVA_VERSION_str); int javaVersionIndex = content.indexOf(JAVA_VERSION_STR);
int _OS_ARCH_index = content.indexOf(OS_ARCH_str); int osArchIndex = content.indexOf(OS_ARCH_STR);
if(_JAVA_VERSION_index != -1 && _OS_ARCH_index != -1) { if(javaVersionIndex != -1 && osArchIndex != -1) {
_JAVA_VERSION_index += JAVA_VERSION_str.length(); javaVersionIndex += JAVA_VERSION_STR.length();
_OS_ARCH_index += OS_ARCH_str.length(); osArchIndex += OS_ARCH_STR.length();
String javaVersion = content.substring(_JAVA_VERSION_index,content.indexOf('"',_JAVA_VERSION_index)); String javaVersion = content.substring(javaVersionIndex,content.indexOf('"', javaVersionIndex));
String[] javaVersionSplit = javaVersion.split("\\."); String[] javaVersionSplit = javaVersion.split("\\.");
int javaVersionInt; int javaVersionInt;
if (javaVersionSplit[0].equals("1")) { if (javaVersionSplit[0].equals("1")) {
@ -201,25 +173,46 @@ public class MultiRTUtils {
} else { } else {
javaVersionInt = Integer.parseInt(javaVersionSplit[0]); javaVersionInt = Integer.parseInt(javaVersionSplit[0]);
} }
Runtime r = new Runtime(name); Runtime runtime = new Runtime(name);
r.arch = content.substring(_OS_ARCH_index,content.indexOf('"',_OS_ARCH_index)); runtime.arch = content.substring(osArchIndex,content.indexOf('"', osArchIndex));
r.javaVersion = javaVersionInt; runtime.javaVersion = javaVersionInt;
r.versionString = javaVersion; runtime.versionString = javaVersion;
retur = r; returnRuntime = runtime;
}else{ }else{
retur = new Runtime(name); returnRuntime = new Runtime(name);
} }
}catch(IOException e) { }catch(IOException e) {
retur = new Runtime(name); returnRuntime = new Runtime(name);
} }
cache.put(name,retur); sCache.put(name, returnRuntime);
return retur; return returnRuntime;
} }
private static void uncompressTarXZ(final File tarFile, final File dest, final ProgressReporterThingy thingy) throws IOException {
dest.mkdirs();
TarArchiveInputStream tarIn = null;
tarIn = new TarArchiveInputStream( private static void copyDummyNativeLib(Context ctx, String name, File dest, String libFolder) throws IOException {
File fileLib = new File(dest, "/"+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();
}
private static void installRuntimeNamedNoRemove(InputStream runtimeInputStream, File dest, RuntimeProgressReporter progressReporter) throws IOException {
File tmp = new File(dest,"temporary");
FileOutputStream fos = new FileOutputStream(tmp);
progressReporter.reportStringProgress(R.string.multirt_progress_caching);
IOUtils.copy(runtimeInputStream,fos);
fos.close();
runtimeInputStream.close();
uncompressTarXZ(tmp,dest,progressReporter);
tmp.delete();
}
private static void uncompressTarXZ(final File tarFile, final File dest, final RuntimeProgressReporter thingy) throws IOException {
dest.mkdirs();
TarArchiveInputStream tarIn = new TarArchiveInputStream(
new XZCompressorInputStream( new XZCompressorInputStream(
new BufferedInputStream( new BufferedInputStream(
new FileInputStream(tarFile) new FileInputStream(tarFile)
@ -251,7 +244,7 @@ public class MultiRTUtils {
// Libcore one support all Android versions // Libcore one support all Android versions
Os.symlink(tarEntry.getName(), tarEntry.getLinkName()); Os.symlink(tarEntry.getName(), tarEntry.getLinkName());
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); Log.e("MultiRT", e.toString());
} }
} else if (tarEntry.isDirectory()) { } else if (tarEntry.isDirectory()) {

View File

@ -23,10 +23,12 @@ import java.io.IOException;
import java.util.List; import java.util.List;
public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAdapter.RTViewHolder> { public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAdapter.RTViewHolder> {
MultiRTConfigDialog dialog;
MultiRTConfigDialog mConfigDialog;
public RTRecyclerViewAdapter(MultiRTConfigDialog dialog) { public RTRecyclerViewAdapter(MultiRTConfigDialog dialog) {
this.dialog = dialog; this.mConfigDialog = dialog;
} }
@NonNull @NonNull
@Override @Override
public RTViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public RTViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -36,102 +38,111 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAd
@Override @Override
public void onBindViewHolder(@NonNull RTViewHolder holder, int position) { public void onBindViewHolder(@NonNull RTViewHolder holder, int position) {
final List<MultiRTUtils.Runtime> runtimes = MultiRTUtils.getRuntimes(); final List<Runtime> runtimes = MultiRTUtils.getRuntimes();
holder.bindRuntime(runtimes.get(position),position); holder.bindRuntime(runtimes.get(position),position);
} }
public boolean isDefaultRuntime(MultiRTUtils.Runtime rt) {
return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name);
}
public void setDefault(MultiRTUtils.Runtime rt){
LauncherPreferences.PREF_DEFAULT_RUNTIME = rt.name;
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
}
@Override @Override
public int getItemCount() { public int getItemCount() {
return MultiRTUtils.getRuntimes().size(); return MultiRTUtils.getRuntimes().size();
} }
public boolean isDefaultRuntime(Runtime rt) {
return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name);
}
public void setDefault(Runtime rt){
LauncherPreferences.PREF_DEFAULT_RUNTIME = rt.name;
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
}
public class RTViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ public class RTViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
final TextView javaVersionView; final TextView mJavaVersionTextView;
final TextView fullJavaVersionView; final TextView mFullJavaVersionTextView;
final ColorStateList defaultColors; final ColorStateList mDefaultColors;
final Button setDefaultButton; final Button mSetDefaultButton;
final Context ctx; final Context mContext;
MultiRTUtils.Runtime currentRuntime; Runtime mCurrentRuntime;
int currentPosition; int mCurrentPosition;
public RTViewHolder(View itemView) { public RTViewHolder(View itemView) {
super(itemView); super(itemView);
javaVersionView = itemView.findViewById(R.id.multirt_view_java_version); mJavaVersionTextView = itemView.findViewById(R.id.multirt_view_java_version);
fullJavaVersionView = itemView.findViewById(R.id.multirt_view_java_version_full); mFullJavaVersionTextView = itemView.findViewById(R.id.multirt_view_java_version_full);
mSetDefaultButton = itemView.findViewById(R.id.multirt_view_setdefaultbtn);
mSetDefaultButton.setOnClickListener(this);
mDefaultColors = mFullJavaVersionTextView.getTextColors();
mContext = itemView.getContext();
itemView.findViewById(R.id.multirt_view_removebtn).setOnClickListener(this); 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, int pos) {
currentRuntime = rt;
currentPosition = pos;
if(rt.versionString != null && Tools.DEVICE_ARCHITECTURE == Architecture.archAsInt(rt.arch)) {
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{
if(rt.versionString == null){
fullJavaVersionView.setText(R.string.multirt_runtime_corrupt);
}else{
fullJavaVersionView.setText(ctx.getString(R.string.multirt_runtime_incompatiblearch, rt.arch));
}
javaVersionView.setText(rt.name);
fullJavaVersionView.setTextColor(Color.RED);
setDefaultButton.setVisibility(View.GONE);
}
} }
@Override @Override
public void onClick(View v) { public void onClick(View view) {
if(v.getId() == R.id.multirt_view_removebtn) { if(view.getId() == R.id.multirt_view_removebtn) {
if (currentRuntime != null) { if (mCurrentRuntime == null) return;
if(MultiRTUtils.getRuntimes().size() < 2 && setDefaultButton.isShown()) {
AlertDialog.Builder bldr = new AlertDialog.Builder(ctx);
bldr.setTitle(R.string.global_error);
bldr.setMessage(R.string.multirt_config_removeerror_last);
bldr.setPositiveButton(android.R.string.ok,(adapter, which)->adapter.dismiss());
bldr.show();
return;
}
final ProgressDialog barrier = new ProgressDialog(ctx); if(MultiRTUtils.getRuntimes().size() < 2 && mSetDefaultButton.isShown()) {
barrier.setMessage(ctx.getString(R.string.global_waiting)); AlertDialog.Builder bldr = new AlertDialog.Builder(mContext);
barrier.setProgressStyle(ProgressDialog.STYLE_SPINNER); bldr.setTitle(R.string.global_error);
barrier.setCancelable(false); bldr.setMessage(R.string.multirt_config_removeerror_last);
barrier.show(); bldr.setPositiveButton(android.R.string.ok,(adapter, which)->adapter.dismiss());
Thread t = new Thread(() -> { bldr.show();
try { return;
MultiRTUtils.removeRuntimeNamed(currentRuntime.name);
} catch (IOException e) {
Tools.showError(itemView.getContext(), e);
}
v.post(() -> {
if(isDefaultRuntime(currentRuntime)) setDefault(MultiRTUtils.getRuntimes().get(0));
barrier.dismiss();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
dialog.dialog.show();
});
});
t.start();
} }
}else if(v.getId() == R.id.multirt_view_setdefaultbtn) {
if(currentRuntime != null) { final ProgressDialog barrier = new ProgressDialog(mContext);
setDefault(currentRuntime); barrier.setMessage(mContext.getString(R.string.global_waiting));
barrier.setProgressStyle(ProgressDialog.STYLE_SPINNER);
barrier.setCancelable(false);
barrier.show();
Thread t = new Thread(() -> {
try {
MultiRTUtils.removeRuntimeNamed(mCurrentRuntime.name);
} catch (IOException e) {
Tools.showError(itemView.getContext(), e);
}
view.post(() -> {
if(isDefaultRuntime(mCurrentRuntime)) setDefault(MultiRTUtils.getRuntimes().get(0));
barrier.dismiss();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
mConfigDialog.mDialog.show();
});
});
t.start();
}else if(view.getId() == R.id.multirt_view_setdefaultbtn) {
if(mCurrentRuntime != null) {
setDefault(mCurrentRuntime);
RTRecyclerViewAdapter.this.notifyDataSetChanged(); RTRecyclerViewAdapter.this.notifyDataSetChanged();
} }
} }
} }
public void bindRuntime(Runtime runtime, int pos) {
mCurrentRuntime = runtime;
mCurrentPosition = pos;
if(runtime.versionString != null && Tools.DEVICE_ARCHITECTURE == Architecture.archAsInt(runtime.arch)) {
mJavaVersionTextView.setText(mContext.getString(R.string.multirt_java_ver, runtime.name, runtime.javaVersion));
mFullJavaVersionTextView.setText(runtime.versionString);
mFullJavaVersionTextView.setTextColor(mDefaultColors);
mSetDefaultButton.setVisibility(View.VISIBLE);
boolean defaultRuntime = isDefaultRuntime(runtime);
mSetDefaultButton.setEnabled(!defaultRuntime);
mSetDefaultButton.setText(defaultRuntime ? R.string.multirt_config_setdefault_already:R.string.multirt_config_setdefault);
return;
}
// Problematic runtime moment
if(runtime.versionString == null){
mFullJavaVersionTextView.setText(R.string.multirt_runtime_corrupt);
}else{
mFullJavaVersionTextView.setText(mContext.getString(R.string.multirt_runtime_incompatiblearch, runtime.arch));
}
mJavaVersionTextView.setText(runtime.name);
mFullJavaVersionTextView.setTextColor(Color.RED);
mSetDefaultButton.setVisibility(View.GONE);
}
} }
} }

View File

@ -16,39 +16,39 @@ import net.kdt.pojavlaunch.R;
import java.util.List; import java.util.List;
public class RTSpinnerAdapter implements SpinnerAdapter { public class RTSpinnerAdapter implements SpinnerAdapter {
final Context ctx; final Context mContext;
List<MultiRTUtils.Runtime> runtimes; List<Runtime> mRuntimes;
public RTSpinnerAdapter(@NonNull Context context, List<MultiRTUtils.Runtime> runtimes) { public RTSpinnerAdapter(@NonNull Context context, List<Runtime> runtimes) {
this.runtimes = runtimes; mRuntimes = runtimes;
MultiRTUtils.Runtime runtime = new MultiRTUtils.Runtime("<Default>"); Runtime runtime = new Runtime("<Default>");
runtime.versionString = ""; runtime.versionString = "";
this.runtimes.add(runtime); mRuntimes.add(runtime);
ctx = context; mContext = context;
} }
@Override @Override
public void registerDataSetObserver(DataSetObserver observer) { public void registerDataSetObserver(DataSetObserver observer) {
//STUB
} }
@Override @Override
public void unregisterDataSetObserver(DataSetObserver observer) { public void unregisterDataSetObserver(DataSetObserver observer) {
//STUB
} }
@Override @Override
public int getCount() { public int getCount() {
return runtimes.size(); return mRuntimes.size();
} }
@Override @Override
public Object getItem(int position) { public Object getItem(int position) {
return runtimes.get(position); return mRuntimes.get(position);
} }
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
return runtimes.get(position).name.hashCode(); return mRuntimes.get(position).name.hashCode();
} }
@Override @Override
@ -59,25 +59,25 @@ public class RTSpinnerAdapter implements SpinnerAdapter {
@NonNull @NonNull
@Override @Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = convertView!=null? View view = convertView != null?
convertView: convertView:
LayoutInflater.from(ctx).inflate(R.layout.multirt_recyclable_view,parent,false); LayoutInflater.from(mContext).inflate(R.layout.multirt_recyclable_view,parent,false);
MultiRTUtils.Runtime rt = runtimes.get(position); Runtime runtime = mRuntimes.get(position);
final TextView javaVersionView = v.findViewById(R.id.multirt_view_java_version); final TextView javaVersionView = view.findViewById(R.id.multirt_view_java_version);
final TextView fullJavaVersionView = v.findViewById(R.id.multirt_view_java_version_full); final TextView fullJavaVersionView = view.findViewById(R.id.multirt_view_java_version_full);
v.findViewById(R.id.multirt_view_removebtn).setVisibility(View.GONE); view.findViewById(R.id.multirt_view_removebtn).setVisibility(View.GONE);
v.findViewById(R.id.multirt_view_setdefaultbtn).setVisibility(View.GONE); view.findViewById(R.id.multirt_view_setdefaultbtn).setVisibility(View.GONE);
if(rt.versionString != null) { if(runtime.versionString != null) {
javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion)); javaVersionView.setText(mContext.getString(R.string.multirt_java_ver, runtime.name, runtime.javaVersion));
fullJavaVersionView.setText(rt.versionString); fullJavaVersionView.setText(runtime.versionString);
}else{ }else{
javaVersionView.setText(rt.name); javaVersionView.setText(runtime.name);
fullJavaVersionView.setText(R.string.multirt_runtime_corrupt); fullJavaVersionView.setText(R.string.multirt_runtime_corrupt);
} }
return v; return view;
} }
@Override @Override
@ -92,7 +92,7 @@ public class RTSpinnerAdapter implements SpinnerAdapter {
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return runtimes.isEmpty(); return mRuntimes.isEmpty();
} }
@Override @Override

View File

@ -0,0 +1,26 @@
package net.kdt.pojavlaunch.multirt;
import java.util.Objects;
public class Runtime {
public Runtime(String name) {
this.name = name;
}
public String name;
public String versionString;
public String arch;
public int javaVersion;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Runtime runtime = (Runtime) o;
return name.equals(runtime.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}

View File

@ -13,13 +13,12 @@ import androidx.appcompat.app.AlertDialog;
import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter; import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter;
import net.kdt.pojavlaunch.tasks.RefreshVersionListTask; import net.kdt.pojavlaunch.multirt.Runtime;
import net.kdt.pojavlaunch.value.PerVersionConfig; import net.kdt.pojavlaunch.value.PerVersionConfig;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -27,7 +26,7 @@ public class PerVersionConfigDialog{
final Context ctx; final Context ctx;
final AlertDialog dialog; final AlertDialog dialog;
final View v; final View v;
List<MultiRTUtils.Runtime> runtimes; List<Runtime> runtimes;
final Spinner javaVMSpinner; final Spinner javaVMSpinner;
final Spinner rendererSpinner; final Spinner rendererSpinner;
final EditText customDirText; final EditText customDirText;
@ -58,7 +57,7 @@ public class PerVersionConfigDialog{
public void refreshRuntimes() { public void refreshRuntimes() {
if(runtimes!=null)runtimes.clear(); if(runtimes!=null)runtimes.clear();
runtimes = MultiRTUtils.getRuntimes(); runtimes = MultiRTUtils.getRuntimes();
//runtimes.add(new MultiRTUtils.Runtime("<Default>")); //runtimes.add(new Runtime("<Default>"));
} }
private void save(DialogInterface i, int which) { private void save(DialogInterface i, int which) {
if(selectedGameVersion == null) { if(selectedGameVersion == null) {
@ -75,7 +74,7 @@ public class PerVersionConfigDialog{
if(rendererSpinner.getSelectedItemPosition() == renderNames.size()) conf1.renderer = null; if(rendererSpinner.getSelectedItemPosition() == renderNames.size()) conf1.renderer = null;
else conf1.renderer = renderNames.get(rendererSpinner.getSelectedItemPosition()); else conf1.renderer = renderNames.get(rendererSpinner.getSelectedItemPosition());
String runtime=((MultiRTUtils.Runtime)javaVMSpinner.getSelectedItem()).name;; String runtime=((Runtime)javaVMSpinner.getSelectedItem()).name;;
if(!runtime.equals("<Default>"))conf1.selectedRuntime=runtime; if(!runtime.equals("<Default>"))conf1.selectedRuntime=runtime;
else conf1.selectedRuntime=null; else conf1.selectedRuntime=null;
@ -97,13 +96,13 @@ public class PerVersionConfigDialog{
refreshRuntimes(); refreshRuntimes();
javaVMSpinner.setAdapter(new RTSpinnerAdapter(ctx,runtimes)); javaVMSpinner.setAdapter(new RTSpinnerAdapter(ctx,runtimes));
{ {
int jvm_index = runtimes.indexOf(new MultiRTUtils.Runtime("<Default>")); int jvm_index = runtimes.indexOf(new Runtime("<Default>"));
int rnd_index = rendererSpinner.getAdapter().getCount()-1; int rnd_index = rendererSpinner.getAdapter().getCount()-1;
if (conf != null) { if (conf != null) {
customDirText.setText(conf.gamePath); customDirText.setText(conf.gamePath);
jvmArgsEditText.setText(conf.jvmArgs); jvmArgsEditText.setText(conf.jvmArgs);
if (conf.selectedRuntime != null) { if (conf.selectedRuntime != null) {
int nindex = runtimes.indexOf(new MultiRTUtils.Runtime(conf.selectedRuntime)); int nindex = runtimes.indexOf(new Runtime(conf.selectedRuntime));
if (nindex != -1) jvm_index = nindex; if (nindex != -1) jvm_index = nindex;
} }
if(conf.renderer != null) { if(conf.renderer != null) {

View File

@ -6,7 +6,6 @@ import android.util.AttributeSet;
import androidx.preference.Preference; import androidx.preference.Preference;
import net.kdt.pojavlaunch.BaseLauncherActivity; import net.kdt.pojavlaunch.BaseLauncherActivity;
import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog;
public class RuntimeManagerPreference extends Preference{ public class RuntimeManagerPreference extends Preference{
public RuntimeManagerPreference(Context ctx) { public RuntimeManagerPreference(Context ctx) {
@ -20,6 +19,6 @@ public class RuntimeManagerPreference extends Preference{
@Override @Override
protected void onClick() { protected void onClick() {
super.onClick(); super.onClick();
((BaseLauncherActivity)this.getContext()).mRuntimeConfigDialog.dialog.show(); ((BaseLauncherActivity)this.getContext()).mRuntimeConfigDialog.mDialog.show();
} }
} }

View File

@ -2,20 +2,18 @@ package net.kdt.pojavlaunch.tasks;
import android.app.*; import android.app.*;
import android.content.*; import android.content.*;
import android.content.res.AssetManager;
import android.graphics.*;
import android.os.*; import android.os.*;
import android.util.*; import android.util.*;
import com.google.gson.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.*;
import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.Runtime;
import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*; import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*; import net.kdt.pojavlaunch.value.*;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import org.apache.commons.io.*; import org.apache.commons.io.*;
@ -97,9 +95,10 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
cfg = new PerVersionConfig.VersionConfig(); cfg = new PerVersionConfig.VersionConfig();
PerVersionConfig.configMap.put(p1[0],cfg); PerVersionConfig.configMap.put(p1[0],cfg);
} }
MultiRTUtils.Runtime r = cfg.selectedRuntime != null?MultiRTUtils.read(cfg.selectedRuntime):MultiRTUtils.read(LauncherPreferences.PREF_DEFAULT_RUNTIME);
if(r.javaVersion < verInfo.javaVersion.majorVersion) { Runtime runtime = cfg.selectedRuntime != null?MultiRTUtils.read(cfg.selectedRuntime):MultiRTUtils.read(LauncherPreferences.PREF_DEFAULT_RUNTIME);
String appropriateRuntime = MultiRTUtils.getNearestJREName(verInfo.javaVersion.majorVersion); if(runtime.javaVersion < verInfo.javaVersion.majorVersion) {
String appropriateRuntime = MultiRTUtils.getNearestJreName(verInfo.javaVersion.majorVersion);
if(appropriateRuntime != null) { if(appropriateRuntime != null) {
cfg.selectedRuntime = appropriateRuntime; cfg.selectedRuntime = appropriateRuntime;
PerVersionConfig.update(); PerVersionConfig.update();