From 24a63b4311792addd7715aeb7ff8197ce194dafc Mon Sep 17 00:00:00 2001 From: An Bui <91354810+AnBui2004@users.noreply.github.com> Date: Wed, 8 Jul 2026 22:20:50 +0700 Subject: [PATCH] 4.3.2 - Fixed Terminal2 not collecting error logs. - Improved detection of whether QEMU returns an error. --- app/build.gradle | 4 +- .../main/java/com/vectras/vm/MainService.java | 38 ++++++++++++------- .../main/java/com/vectras/vm/VMManager.java | 4 +- .../com/vectras/vm/main/core/MainStartVM.java | 6 ++- .../java/com/vectras/vterm/Terminal2.java | 1 + web/data/UpdateConfig.json | 8 ++-- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 181b40f..03201c9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "com.vectras.vm" minSdk minApi targetSdk targetApi - versionCode 135 - versionName "4.3.1" + versionCode 136 + versionName "4.3.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true diff --git a/app/src/main/java/com/vectras/vm/MainService.java b/app/src/main/java/com/vectras/vm/MainService.java index 6c13776..0f5a56b 100644 --- a/app/src/main/java/com/vectras/vm/MainService.java +++ b/app/src/main/java/com/vectras/vm/MainService.java @@ -16,6 +16,8 @@ import android.util.Log; import androidx.core.app.NotificationCompat; +import com.vectras.vm.main.core.MainStartVM; +import com.vectras.vm.manager.VmServiceManager; import com.vectras.vm.utils.ClipboardUltils; import com.vectras.vm.utils.DialogUtils; import com.vectras.vterm.Terminal; @@ -26,7 +28,7 @@ import java.util.Objects; public class MainService extends Service { public static String CHANNEL_ID = "Vectras VM Service"; private final int NOTIFICATION_ID = 1; - private final String MACHINE_NAME = "Vectras VM"; + public static String vmName = "Vectras VM"; public static String env = null; private static String TAG = "MainService"; public static MainService service; @@ -48,7 +50,7 @@ public class MainService extends Service { Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(getString(R.string.app_name)) - .setContentText(MACHINE_NAME + " running in background.") + .setContentText("The virtual machines are running...") .setSmallIcon(R.drawable.ic_vectras_vm_48) .addAction(R.drawable.close_24px, getString(R.string.stop), pStopSelf) .build(); @@ -57,7 +59,7 @@ public class MainService extends Service { if (env != null) { if (service != null) { - startCommand(env, activityContext); + startCommand(vmName, env, activityContext); } } else { Log.e(TAG, "env is null"); @@ -77,10 +79,13 @@ public class MainService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null && Objects.equals(intent.getAction(), STOP_ACTION)) { - VMManager.killallqemuprocesses(this); - stopForeground(true); - stopSelf(); - return START_NOT_STICKY; + new Thread(() -> { + VMManager.killallqemuprocesses(this); + new Handler(Looper.getMainLooper()).post(() -> { + stopForeground(true); + stopSelf(); + }); + }).start(); } return START_NOT_STICKY; } @@ -102,7 +107,7 @@ public class MainService extends Service { } } - public static void startCommand(String env, Context context) { + public static void startCommand(String vmName, String env, Context context) { Terminal2 terminal2 = new Terminal2(activityContext); terminal2.setDefaultShellBash(); terminal2.setStartup("export XDG_RUNTIME_DIR=/tmp && unset PULSE_SERVER"); @@ -123,13 +128,18 @@ public class MainService extends Service { return; } - new Handler(Looper.getMainLooper()).post(() -> { - if (VMManager.isExecutedCommandError(command, log, context)) - return; + if (!(log.trim().isEmpty() || log.trim().equals(MainStartVM.TAG_FINISHED_WITHOUT_ERROR))) { + new Handler(Looper.getMainLooper()).post(() -> { + if (!VMManager.isExecutedCommandError(command, log, context)) { + String finalLog = log.contains(MainStartVM.TAG_FINISHED_WITHOUT_ERROR) ? log.substring(0, log.lastIndexOf(MainStartVM.TAG_FINISHED_WITHOUT_ERROR) - 1) : log; - DialogUtils.twoDialog(context, "Execution Result", log, context.getString(R.string.copy), context.getString(R.string.close), true, R.drawable.round_terminal_24, true, - () -> ClipboardUltils.copyToClipboard(context, log), null, null); - }); + DialogUtils.twoDialog(context, vmName, finalLog, context.getString(R.string.copy), context.getString(R.string.close), true, R.drawable.stack_24px, true, + () -> ClipboardUltils.copyToClipboard(context, log), null, null); + } + }); + } + + VmServiceManager.stopService(context); } @Override diff --git a/app/src/main/java/com/vectras/vm/VMManager.java b/app/src/main/java/com/vectras/vm/VMManager.java index cafc2c3..61425b0 100644 --- a/app/src/main/java/com/vectras/vm/VMManager.java +++ b/app/src/main/java/com/vectras/vm/VMManager.java @@ -666,8 +666,6 @@ public class VMManager { return false; } - VmServiceManager.stopService(_activity); - if (_command.contains("qemu-system") && _result.contains("Killed")) { isQemuStopedWithError = true; return true; @@ -735,7 +733,7 @@ public class VMManager { }, null, null); return false; - } else if (_command.contains("qemu-system") && _result.contains("qemu-system") && !_result.contains("warning:")) { + } else if (!_result.contains(MainStartVM.TAG_FINISHED_WITHOUT_ERROR)) { //Error code: UNKNOW_ERROR DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.vm_could_not_be_run_content) + "\n\n" + _result, R.drawable.error_96px); _activity.stopService(new Intent(_activity, MainService.class)); diff --git a/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java b/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java index ba72d09..2073dc9 100644 --- a/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java +++ b/app/src/main/java/com/vectras/vm/main/core/MainStartVM.java @@ -35,6 +35,7 @@ import java.io.File; public class MainStartVM { public static final String TAG = "HomeStartVM"; + public static final String TAG_FINISHED_WITHOUT_ERROR = "This VM has shut down."; public static boolean skipIDEwithARM64DialogInStartVM = false; public static boolean breakNow = false; public static final Handler handlerForLaunch = new Handler(Looper.getMainLooper()); @@ -297,7 +298,7 @@ public class MainStartVM { ) { VMManager.isQemuStopedWithError = false; - String cleanUpCommand = "; rm -r " + Config.getCacheVMPath(vmID); + String cleanUpCommand = " && echo \"" + TAG_FINISHED_WITHOUT_ERROR + "\"\nrm -r " + Config.getCacheVMPath(vmID); String finalCommand = VMManager.addAudioDevWav(vmID, String.format(runCommandFormat, env + cleanUpCommand)); @@ -314,11 +315,12 @@ public class MainStartVM { } if (ServiceUtils.isServiceRunning(context, MainService.class)) { - MainService.startCommand(finalCommand, context); + MainService.startCommand(vmName, finalCommand, context); } else { Intent serviceIntent = new Intent(context, MainService.class); MainService.activityContext = context; MainService.env = finalCommand; + MainService.vmName = vmName; MainService.CHANNEL_ID = vmName; if (SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(serviceIntent); diff --git a/app/src/main/java/com/vectras/vterm/Terminal2.java b/app/src/main/java/com/vectras/vterm/Terminal2.java index 4949063..3d2d811 100644 --- a/app/src/main/java/com/vectras/vterm/Terminal2.java +++ b/app/src/main/java/com/vectras/vterm/Terminal2.java @@ -107,6 +107,7 @@ public class Terminal2 { try { ProcessBuilder processBuilder = new ProcessBuilder(); + processBuilder.redirectErrorStream(true); String filesDir = Objects.requireNonNull(context.getFilesDir().getAbsolutePath()); diff --git a/web/data/UpdateConfig.json b/web/data/UpdateConfig.json index ab11e24..63d593c 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": "