diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java index 002506aa9..4ef2846ec 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java @@ -2,14 +2,21 @@ package net.kdt.pojavlaunch; import android.app.*; import android.content.*; +import android.database.Cursor; +import android.net.Uri; +import android.provider.OpenableColumns; import android.text.*; import android.text.method.*; import android.view.*; import android.widget.*; + +import androidx.annotation.Nullable; import androidx.appcompat.app.*; import com.kdt.pickafile.*; import java.io.*; import net.kdt.pojavlaunch.fragments.*; +import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; +import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.tasks.*; @@ -22,6 +29,7 @@ public abstract class BaseLauncherActivity extends BaseActivity { public CrashFragment mCrashView; public ProgressBar mLaunchProgress; public Spinner mVersionSelector; + public MultiRTConfigDialog mRuntimeConfigDialog; public TextView mLaunchTextStatus, mTextVersion; public JMinecraftVersionList mVersionList; @@ -171,10 +179,12 @@ public abstract class BaseLauncherActivity extends BaseActivity { } } }; - LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener); } + LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener); new RefreshVersionListTask(this).execute(); System.out.println("call to onResumeFragments"); + mRuntimeConfigDialog = new MultiRTConfigDialog(); + mRuntimeConfigDialog.prepare(this); try{ final ProgressDialog barrier = new ProgressDialog(this); barrier.setMessage(getString(R.string.global_waiting)); @@ -224,7 +234,61 @@ public abstract class BaseLauncherActivity extends BaseActivity { } System.out.println("call to onResumeFragments; E"); } - + public String getFileName(Uri uri) { + String result = null; + if (uri.getScheme().equals("content")) { + Cursor cursor = getContentResolver().query(uri, null, null, null, null); + try { + if (cursor != null && cursor.moveToFirst()) { + result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); + } + } finally { + cursor.close(); + } + } + if (result == null) { + result = uri.getPath(); + int cut = result.lastIndexOf('/'); + if (cut != -1) { + result = result.substring(cut + 1); + } + } + return result; + } + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode,resultCode,data); + if(requestCode == MultiRTConfigDialog.MULTIRT_PICK_RUNTIME && resultCode == Activity.RESULT_OK) { + if (data != null) { + final Uri uri = data.getData(); + final ProgressDialog barrier = new ProgressDialog(this); + barrier.setMessage(getString(R.string.global_waiting)); + barrier.setProgressStyle(barrier.STYLE_SPINNER); + barrier.setCancelable(false); + barrier.show(); + Thread t = new Thread(()->{ + try { + MultiRTUtils.installRuntimeNamed(getContentResolver().openInputStream(uri), getFileName(uri), + (resid, stuff) -> BaseLauncherActivity.this.runOnUiThread( + () -> barrier.setMessage(BaseLauncherActivity.this.getString(resid,stuff)))); + }catch (IOException e) { + Tools.showError(BaseLauncherActivity.this + ,e); + } + BaseLauncherActivity.this.runOnUiThread(new Runnable() { + @Override + public void run() { + barrier.dismiss(); + mRuntimeConfigDialog.refresh(); + mRuntimeConfigDialog.dialog.show(); + } + }); + }); + t.start(); + } + } + } + // Catching touch exception @Override public boolean onTouchEvent(MotionEvent event) { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java new file mode 100644 index 000000000..d1e9c1469 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java @@ -0,0 +1,49 @@ +package net.kdt.pojavlaunch.multirt; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import net.kdt.pojavlaunch.BaseLauncherActivity; +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 AlertDialog dialog; + public RecyclerView dialogView; + public void prepare(BaseLauncherActivity ctx) { + AlertDialog.Builder builder = new AlertDialog.Builder(ctx); + builder.setTitle(R.string.multirt_config_title); + dialogView = new RecyclerView(ctx); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx); + linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); + dialogView.setLayoutManager(linearLayoutManager); + dialogView.setAdapter(new RTRecyclerViewAdapter(this)); + builder.setView(dialogView); + builder.setPositiveButton(R.string.multirt_config_add, new DialogInterface.OnClickListener() { + @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); + } + }); + builder.setNegativeButton(R.string.mcn_exit_call, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + dialog = builder.create(); + } + public void refresh() { + dialogView.getAdapter().notifyDataSetChanged(); + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MultiRTUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java similarity index 81% rename from app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MultiRTUtils.java rename to app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java index 249f92731..cde36117c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MultiRTUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java @@ -1,7 +1,8 @@ -package net.kdt.pojavlaunch.utils; +package net.kdt.pojavlaunch.multirt; import android.annotation.SuppressLint; import android.system.Os; +import android.util.Log; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.Tools; @@ -32,25 +33,31 @@ public class MultiRTUtils { public String versionString; public int javaVersion; } + public static interface ProgressReporterThingy { + void reportStringProgress(int resid, Object ... stuff); + } private static File runtimeFolder = new File(Tools.MULTIRT_HOME); private static final String JAVA_VERSION_str = "JAVA_VERSION=\""; public static List getRuntimes() { ArrayList ret = new ArrayList<>(); + System.out.println("Fetch runtime list"); for(File f : runtimeFolder.listFiles()) { ret.add(read(f.getName())); } + return ret; } - public static Runtime installRuntimeNamed(InputStream runtimeInputStream, String name) throws IOException { + public static Runtime installRuntimeNamed(InputStream runtimeInputStream, String name, ProgressReporterThingy thingy) throws IOException { File dest = new File(runtimeFolder,"/"+name); File tmp = new File(dest,"temporary"); if(dest.exists()) FileUtils.deleteDirectory(dest); dest.mkdirs(); FileOutputStream fos = new FileOutputStream(tmp); + thingy.reportStringProgress(R.string.multirt_progress_caching); IOUtils.copy(runtimeInputStream,fos); fos.close(); runtimeInputStream.close(); - uncompressTarXZ(tmp,dest); + uncompressTarXZ(tmp,dest,thingy); tmp.delete(); return read(name); } @@ -74,17 +81,17 @@ public class MultiRTUtils { if(_JAVA_VERSION_index != -1) { _JAVA_VERSION_index += JAVA_VERSION_str.length(); String javaVersion = content.substring(_JAVA_VERSION_index,content.indexOf('"',_JAVA_VERSION_index)); - String[] javaVersionSplit = javaVersion.split("."); - int javaVersionInt; - if(javaVersionSplit[0].equals("1")) { - javaVersionInt = Integer.parseInt(javaVersionSplit[1]); - }else{ - javaVersionInt = Integer.parseInt(javaVersionSplit[0]); - } - Runtime r = new Runtime(name); - r.javaVersion = javaVersionInt; - r.versionString = javaVersion; - retur = r; + String[] javaVersionSplit = javaVersion.split("\\."); + int javaVersionInt; + if (javaVersionSplit[0].equals("1")) { + javaVersionInt = Integer.parseInt(javaVersionSplit[1]); + } else { + javaVersionInt = Integer.parseInt(javaVersionSplit[0]); + } + Runtime r = new Runtime(name); + r.javaVersion = javaVersionInt; + r.versionString = javaVersion; + retur = r; }else{ retur = new Runtime(name); } @@ -94,7 +101,7 @@ public class MultiRTUtils { cache.put(name,retur); return retur; } - private static void uncompressTarXZ(final File tarFile, final File dest) throws IOException { + private static void uncompressTarXZ(final File tarFile, final File dest, final ProgressReporterThingy thingy) throws IOException { dest.mkdirs(); TarArchiveInputStream tarIn = null; @@ -121,6 +128,7 @@ public class MultiRTUtils { } final String tarEntryName = tarEntry.getName(); // publishProgress(null, "Unpacking " + tarEntry.getName()); + thingy.reportStringProgress(R.string.global_unpacking,tarEntryName); File destPath = new File(dest, tarEntry.getName()); if (tarEntry.isSymbolicLink()) { destPath.getParentFile().mkdirs(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java new file mode 100644 index 000000000..34f11796e --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java @@ -0,0 +1,96 @@ +package net.kdt.pojavlaunch.multirt; + +import android.app.ProgressDialog; +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import net.kdt.pojavlaunch.R; +import net.kdt.pojavlaunch.Tools; + +import java.io.IOException; +import java.util.List; + +public class RTRecyclerViewAdapter extends RecyclerView.Adapter { + MultiRTConfigDialog dialog; + public RTRecyclerViewAdapter(MultiRTConfigDialog dialog) { + this.dialog = dialog; + } + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View recyclableView = LayoutInflater.from(parent.getContext()).inflate(R.layout.multirt_recyclable_view,parent,false); + return new RTViewHolder(recyclableView); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + final List runtimes = MultiRTUtils.getRuntimes(); + ((RTViewHolder)holder).bindRuntime(runtimes.get(position)); + } + + @Override + public int getItemCount() { + return MultiRTUtils.getRuntimes().size(); + } + public class RTViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ + final TextView javaVersionView; + final TextView fullJavaVersionView; + final ColorStateList defaultColors; + final Context ctx; + MultiRTUtils.Runtime currentRuntime; + 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); + defaultColors = fullJavaVersionView.getTextColors(); + ctx = itemView.getContext(); + } + public void bindRuntime(MultiRTUtils.Runtime rt) { + currentRuntime = rt; + if(rt.versionString != null) { + javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion)); + fullJavaVersionView.setText(rt.versionString); + fullJavaVersionView.setTextColor(defaultColors); + + }else{ + javaVersionView.setText(rt.name); + fullJavaVersionView.setText(R.string.multirt_runtime_corrupt); + fullJavaVersionView.setTextColor(Color.RED); + } + } + + @Override + public void onClick(View v) { + 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(()->{ + try { + MultiRTUtils.removeRuntimeNamed(currentRuntime.name); + }catch (IOException e) { + Tools.showError(itemView.getContext(),e); + } + v.post(() ->{ + barrier.dismiss(); + RTRecyclerViewAdapter.this.notifyDataSetChanged(); + dialog.dialog.show(); + }); + }); + t.start(); + } + } + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java new file mode 100644 index 000000000..24ff16977 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java @@ -0,0 +1,25 @@ +package net.kdt.pojavlaunch.prefs; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.preference.Preference; + +import net.kdt.pojavlaunch.BaseLauncherActivity; +import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; + +public class RuntimeManagerPreference extends Preference{ + public RuntimeManagerPreference(Context ctx) { + this(ctx, null); + } + + public RuntimeManagerPreference(Context ctx, AttributeSet attrs) { + super(ctx, attrs); + setPersistent(false); + } + @Override + protected void onClick() { + super.onClick(); + ((BaseLauncherActivity)this.getContext()).mRuntimeConfigDialog.dialog.show(); + } +} diff --git a/app_pojavlauncher/src/main/res/layout/multirt_recyclable_view.xml b/app_pojavlauncher/src/main/res/layout/multirt_recyclable_view.xml new file mode 100644 index 000000000..d600bd198 --- /dev/null +++ b/app_pojavlauncher/src/main/res/layout/multirt_recyclable_view.xml @@ -0,0 +1,42 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index cac231ecb..2974789d2 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -211,4 +211,12 @@ The current amount of free RAM (%d) is lower than allocated RAM (%d), which may lead to crashes. Change the allocation if the game crashes. Memory allocation Controls how much memory is given to Minecraft + %s (Java %d) + Corrupted Java Runtime + Java VMs + Add new + Import new Java VM + Runtime Manager + Manage installed Java VMs + Caching... diff --git a/app_pojavlauncher/src/main/res/xml/pref_main.xml b/app_pojavlauncher/src/main/res/xml/pref_main.xml index 39c29f398..b332b9dcb 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_main.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_main.xml @@ -10,7 +10,9 @@ android:summary="@string/mcl_setting_subtitle_uninstalljre" android:title="@string/mcl_setting_title_uninstalljre" app2:icon="@drawable/rm_jre" /> - +