diff --git a/app/build.gradle b/app/build.gradle index a57b618..2aabf36 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "com.vectras.vm" minSdk minApi targetSdk targetApi - versionCode 75 - versionName "3.7.1" + versionCode 76 + versionName "3.7.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true diff --git a/app/src/main/java/com/vectras/vm/Fragment/LoggerDialogFragment.java b/app/src/main/java/com/vectras/vm/Fragment/LoggerDialogFragment.java index 00a235b..892fa78 100644 --- a/app/src/main/java/com/vectras/vm/Fragment/LoggerDialogFragment.java +++ b/app/src/main/java/com/vectras/vm/Fragment/LoggerDialogFragment.java @@ -1,24 +1,20 @@ package com.vectras.vm.Fragment; -import android.app.Activity; import android.app.Dialog; +import android.content.DialogInterface; +import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; -import androidx.appcompat.app.AlertDialog; +import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; import android.view.Window; import android.widget.Toast; -import com.vectras.qemu.MainSettingsManager; import com.vectras.vm.R; import com.vectras.vm.VectrasApp; import com.vectras.vm.adapter.LogsAdapter; @@ -27,28 +23,25 @@ import com.vectras.vm.logger.VectrasStatus; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.Objects; import java.util.Timer; import java.util.TimerTask; public class LoggerDialogFragment extends DialogFragment { + private final String TAG = "LoggerDialogFragment"; + private final Timer _timer = new Timer(); + private boolean isReading; - private final String CREDENTIAL_SHARED_PREF = "settings_prefs"; - private LogsAdapter mLogAdapter; - private RecyclerView logList; - private Timer _timer = new Timer(); - private TimerTask t; - Activity activity; - + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - activity = getActivity(); - final Dialog alertDialog = new Dialog(getActivity(), R.style.MainDialogTheme); + final Dialog alertDialog = new Dialog(requireActivity(), R.style.MainDialogTheme); alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); + Objects.requireNonNull(alertDialog.getWindow()).setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); alertDialog.setContentView(R.layout.fragment_logs); LinearLayoutManager layoutManager = new LinearLayoutManager(VectrasApp.getApp()); - mLogAdapter = new LogsAdapter(layoutManager, VectrasApp.getApp()); - logList = (RecyclerView) alertDialog.findViewById(R.id.recyclerLog); + LogsAdapter mLogAdapter = new LogsAdapter(layoutManager, VectrasApp.getApp()); + RecyclerView logList = alertDialog.findViewById(R.id.recyclerLog); logList.setAdapter(mLogAdapter); logList.setLayoutManager(layoutManager); mLogAdapter.scrollToLastPosition(); @@ -60,32 +53,54 @@ public class LoggerDialogFragment extends DialogFragment { BufferedReader bufferedReader2 = new BufferedReader( new InputStreamReader(process2.getInputStream())); - t = new TimerTask() { + TimerTask t = new TimerTask() { @Override public void run() { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - try { - if (bufferedReader.readLine() != null || bufferedReader2.readLine() != null) { - String logLine = bufferedReader.readLine(); - String logLine2 = bufferedReader2.readLine(); - VectrasStatus.logError("[E] "+logLine+""); - VectrasStatus.logError("[W] "+logLine2+""); - } - } catch (IOException e) { - throw new RuntimeException(e); + new Thread(() -> { + if (isReading) return; + String logLine = ""; + String logLine2 = ""; + try { + isReading = true; + if (bufferedReader.readLine() != null || bufferedReader2.readLine() != null) { + logLine = bufferedReader.readLine(); + logLine2 = bufferedReader2.readLine(); } + + String finalLogLine = logLine; + String finalLogLine1 = logLine2; + if (!isAdded()) { + _timer.cancel(); + return; + } + requireActivity().runOnUiThread(() -> { + if (!finalLogLine.isEmpty()) + VectrasStatus.logError("[E] " + finalLogLine + ""); + if (!finalLogLine1.isEmpty()) + VectrasStatus.logError("[W] " + finalLogLine1 + ""); + isReading = false; + }); + } catch (IOException e) { + Log.e(TAG, "onCreateDialog: ", e); + } finally { + isReading = false; } - }); + }).start(); } }; - _timer.scheduleAtFixedRate(t, (int) (0), (int) (100)); + _timer.schedule(t, 0, 1000); } catch (IOException e) { - Toast.makeText(activity, "There was an error: " + Log.getStackTraceString(e), Toast.LENGTH_LONG).show(); - e.printStackTrace(); + if (isAdded()) + Toast.makeText(requireActivity(), "There was an error: " + Log.getStackTraceString(e), Toast.LENGTH_LONG).show(); + Log.e(TAG, "onCreateDialog: ", e); } + alertDialog.show(); return alertDialog; } + + public void onDismiss(@NonNull DialogInterface dialogInterface) { + super.onDismiss(dialogInterface); + _timer.cancel(); + } } \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java b/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java index de35d1e..fbb7bdf 100644 --- a/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java +++ b/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java @@ -351,7 +351,7 @@ public class VMCreatorActivity extends AppCompatActivity { if (isImportingCVBI) return; if (!created && !modify) { - new Thread(() -> FileUtils.deleteDirectory(AppConfig.vmFolder + vmID)).start(); + new Thread(() -> FileUtils.delete(new File (AppConfig.vmFolder + vmID))).start(); } modify = false; finish(); @@ -466,7 +466,7 @@ public class VMCreatorActivity extends AppCompatActivity { String filePath; try { File selectedFilePath = new File(getPath(uri)); - filePath = selectedFilePath.getPath(); + filePath = selectedFilePath.getAbsolutePath(); } catch (Exception e) { filePath = ""; } @@ -930,7 +930,7 @@ public class VMCreatorActivity extends AppCompatActivity { progressDialog.show(); - Log.i(TAG, "importRom: Extracting from " + filePath + " to " + AppConfig.vmFolder + vmID); + Log.i(TAG, "importRom: Extracting with " + (isUseUri ? "uri" : "path") + " from " + filePath + " to " + AppConfig.vmFolder + vmID); new Thread(() -> { boolean result = isUseUri ? ZipUtils.extract( diff --git a/app/src/main/java/com/vectras/vm/utils/FileUtils.java b/app/src/main/java/com/vectras/vm/utils/FileUtils.java index 37bc566..b6cb6e4 100644 --- a/app/src/main/java/com/vectras/vm/utils/FileUtils.java +++ b/app/src/main/java/com/vectras/vm/utils/FileUtils.java @@ -752,25 +752,32 @@ public class FileUtils { return true; } + @Deprecated public static void deleteDirectory(String _pathToDelete) { - File _dir = new File(_pathToDelete); - if (_dir.isDirectory()) { - String[] children = _dir.list(); + delete(new File(_pathToDelete)); + } + + public static boolean delete(File file) { + if (!file.exists()) return true; + if (file.isDirectory()) { + String[] children = file.list(); if (children == null) { - Log.e("ERROR", "Deletion failed. " + _dir); - return; + Log.e(TAG, "delete: Failed:" + file); + return false; } for (int i = 0; i < children.length; i++) { - File temp = new File(_dir, children[i]); - deleteDirectory(String.valueOf(temp)); + File temp = new File(file, children[i]); + delete(temp); } } - boolean success = _dir.delete(); + boolean success = file.delete(); if (!success) { - Log.e("ERROR", "Deletion failed. " + _dir); + Log.e(TAG, "delete: Failed: " + file); } + + return success; } public static boolean canRead(String filePath) { diff --git a/app/src/main/java/com/vectras/vm/utils/NumberUtils.java b/app/src/main/java/com/vectras/vm/utils/NumberUtils.java index e2e4f92..2a0ef8e 100644 --- a/app/src/main/java/com/vectras/vm/utils/NumberUtils.java +++ b/app/src/main/java/com/vectras/vm/utils/NumberUtils.java @@ -1,5 +1,7 @@ package com.vectras.vm.utils; +import java.util.Locale; + public class NumberUtils { public static int safeLongToInt(long l) { if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) { @@ -7,4 +9,14 @@ public class NumberUtils { } return (int) l; } + + public static String getFormatSizeFromMB(long mb) { + if (mb < 1024) { + return mb + " MB"; + } else { + double gb = mb / 1024.0; + return String.format(Locale.US, "%.2f GB", gb); + } + } + } diff --git a/app/src/main/java/com/vectras/vm/utils/ZipUtils.java b/app/src/main/java/com/vectras/vm/utils/ZipUtils.java index 444e2e6..6377760 100644 --- a/app/src/main/java/com/vectras/vm/utils/ZipUtils.java +++ b/app/src/main/java/com/vectras/vm/utils/ZipUtils.java @@ -1,5 +1,7 @@ package com.vectras.vm.utils; +import static android.os.Build.VERSION.SDK_INT; + import android.app.Activity; import android.content.Context; import android.net.Uri; @@ -14,7 +16,6 @@ import com.vectras.vm.R; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -138,12 +139,12 @@ public class ZipUtils { if (MainSettingsManager.getSmartSizeCalculation(context)) { // >7GB - sizeCalculation = DeviceUtils.totalMemoryCapacity(context) > 7L * 1024 * 1024 * 1024; + sizeCalculation = SDK_INT < 31 && DeviceUtils.totalMemoryCapacity(context) > 7L * 1024 * 1024 * 1024; } else { - sizeCalculation = true; + sizeCalculation = false; } - //Can be skipped as it may not get the size and is time consuming. + //Can be skipped as it may not get the size and is time-consuming. if (sizeCalculation) { InputStream inputStream = context.getContentResolver().openInputStream(fileZip); @@ -190,12 +191,10 @@ public class ZipUtils { long lastProgress = -1; while ((len = zin.read(buffer)) > 0) { fos.write(buffer, 0, len); - - if (totalSize < 0) { - fileExtracted += len; - extractedSize += len; - - long progress = (totalSize > 0) ? (extractedSize * 100 / totalSize) : 0; + fileExtracted += len; + extractedSize += len; + if (totalSize > 0) { + long progress = extractedSize * 100 / totalSize; if (progress > lastProgress) { lastProgress = progress; @@ -209,6 +208,20 @@ public class ZipUtils { (int) progress ); } + } else { + if (extractedSize > lastProgress + (1024 * 1024) || lastProgress < 1) { + lastProgress = extractedSize; + long mb = extractedSize / (1024 * 1024); + updateStatus( + statusTextView, + progressBar, + (mb == 0 ? + context.getString(R.string.importing) : + context.getString(R.string.completed) + " " + NumberUtils.getFormatSizeFromMB(mb)) + + "\n" + context.getString(R.string.please_stay_here), + 0 + ); + } } } fos.close(); @@ -369,7 +382,7 @@ public class ZipUtils { if (progressbar.getMax() != 100) progressbar.setMax(100); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (SDK_INT >= Build.VERSION_CODES.N) { progressbar.setProgress(progress, true); } else { progressbar.setProgress(progress); diff --git a/app/src/main/java/com/vectras/vm/x11/LorieView.java b/app/src/main/java/com/vectras/vm/x11/LorieView.java index 4e62cb8..978d08c 100644 --- a/app/src/main/java/com/vectras/vm/x11/LorieView.java +++ b/app/src/main/java/com/vectras/vm/x11/LorieView.java @@ -201,7 +201,6 @@ public class LorieView extends SurfaceView implements InputStub { @Override public void sendMouseWheelEvent(float deltaX, float deltaY) { - if (!PackageUtils.isClassAvailable("com.termux.x11.CmdEntryPoint")) return; sendMouseEvent(deltaX, deltaY, BUTTON_SCROLL, false, true); } diff --git a/app/src/main/java/com/vectras/vm/x11/input/InputEventSender.java b/app/src/main/java/com/vectras/vm/x11/input/InputEventSender.java index f54587c..207107f 100644 --- a/app/src/main/java/com/vectras/vm/x11/input/InputEventSender.java +++ b/app/src/main/java/com/vectras/vm/x11/input/InputEventSender.java @@ -14,6 +14,7 @@ import android.graphics.PointF; import android.view.KeyEvent; import android.view.MotionEvent; +import com.vectras.vm.utils.PackageUtils; import com.vectras.vm.x11.X11Activity; import java.util.List; @@ -75,6 +76,7 @@ public final class InputEventSender { } public void sendCursorMove(float x, float y, boolean relative) { + if (!PackageUtils.isClassAvailable("com.termux.x11.CmdEntryPoint")) return; mInjector.sendMouseEvent(x, y, BUTTON_UNDEFINED, false, relative); } diff --git a/web/data/UpdateConfig.json b/web/data/UpdateConfig.json index efafe7f..c35d92f 100644 --- a/web/data/UpdateConfig.json +++ b/web/data/UpdateConfig.json @@ -5,11 +5,11 @@ "url": "https://github.com/xoureldeen/Vectras-VM-Android/releases", "Message": "

3.7.0

\nBugs fixed.", "cancellable": true, - "versionCodeBeta":"75", - "versionNameBeta":"3.7.1", - "versionNameBetas":"3.0.0,3.1.0,3.2.1,3.2.2,3.2.3,3.2.4,3.2.5,3.2.6,3.2.7,3.2.8,3.2.9,3.2.10,3.3.1,3.3.2,3.3.3,3.3.4,3.3.5,3.3.6,3.3.7,3.3.8,3.3.9,3.4.1,3.4.2,3.4.3,3.4.4,3.4.5,3.4.6,3.4.7,3.4.8,3.4.9,3.5.1,3.5.2,3.5.3,3.5.4,3.5.5,3.5.6,3.5.7,3.5.8,3.5.9,3.6.1,3.6.2,3.6.3,3.6.4,3.6.5,3.6.6,3.6.7,3.6.8,3.6.9,3.7.0,3.7.1", + "versionCodeBeta":"76", + "versionNameBeta":"3.7.2", + "versionNameBetas":"3.0.0,3.1.0,3.2.1,3.2.2,3.2.3,3.2.4,3.2.5,3.2.6,3.2.7,3.2.8,3.2.9,3.2.10,3.3.1,3.3.2,3.3.3,3.3.4,3.3.5,3.3.6,3.3.7,3.3.8,3.3.9,3.4.1,3.4.2,3.4.3,3.4.4,3.4.5,3.4.6,3.4.7,3.4.8,3.4.9,3.5.1,3.5.2,3.5.3,3.5.4,3.5.5,3.5.6,3.5.7,3.5.8,3.5.9,3.6.1,3.6.2,3.6.3,3.6.4,3.6.5,3.6.6,3.6.7,3.6.8,3.6.9,3.7.0,3.7.1,3.7.2", "sizeBeta": "45 MB", "urlBeta": "https://github.com/AnBui2004/Vectras-VM-Emu-Android/releases", - "MessageBeta": "

3.7.1

Bugs fixed.", + "MessageBeta": "

3.7.2

Bugs fixed.", "cancellableBeta": true }