mirror of
https://github.com/xoureldeen/Vectras-VM-Android.git
synced 2026-05-02 16:20:30 +00:00
initial commit
This commit is contained in:
parent
250d795823
commit
48648e4ab5
10 changed files with 201 additions and 169 deletions
|
|
@ -106,7 +106,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
private AdRequest adRequest;
|
||||
public DrawerLayout mainDrawer;
|
||||
private String TAG = "MainActivity";
|
||||
public static /**/ LinearLayout extVncLayout;
|
||||
public static /**/ LinearLayout extViewerLayout;
|
||||
public static AppBarLayout appbar;
|
||||
public TextView totalRam;
|
||||
public TextView usedRam;
|
||||
|
|
@ -135,10 +135,16 @@ public class MainActivity extends AppCompatActivity {
|
|||
appbar = findViewById(R.id.appbar);
|
||||
appbar.setExpanded(false);
|
||||
|
||||
extVncLayout = findViewById(R.id.extVnc);
|
||||
extViewerLayout = findViewById(R.id.extVnc);
|
||||
|
||||
TextView extTitle = findViewById(R.id.extTitle);
|
||||
TextView tvLogin = findViewById(R.id.tvLogin);
|
||||
tvLogin.setText("LOGIN --> " + Config.defaultVNCHost + ":" + (5900 + Config.defaultVNCPort)/* + "\nPASSWORD --> " + Config.defaultVNCPasswd*/);
|
||||
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
|
||||
tvLogin.setText("LOGIN --> " + Config.defaultVNCHost + ":" + (5900 + Config.defaultVNCPort)/* + "\nPASSWORD --> " + Config.defaultVNCPasswd*/);
|
||||
} else {
|
||||
extTitle.setText("EXTERNAL X11");
|
||||
tvLogin.setText("Now Open Termux X11");
|
||||
}
|
||||
|
||||
Button stopBtn = findViewById(R.id.stopBtn);
|
||||
stopBtn.setOnClickListener(new View.OnClickListener() {
|
||||
|
|
@ -150,7 +156,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
Terminal vterm = new Terminal(activity);
|
||||
vterm.executeShellCommand("killall qemu-system-*", false, activity);
|
||||
|
||||
extVncLayout.setVisibility(View.GONE);
|
||||
extViewerLayout.setVisibility(View.GONE);
|
||||
appbar.setExpanded(false);
|
||||
}
|
||||
});
|
||||
|
|
@ -774,7 +780,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
|
||||
if (MainSettingsManager.getVncExternal(MainActivity.activity)) {
|
||||
extVncLayout.setVisibility(View.VISIBLE);
|
||||
extViewerLayout.setVisibility(View.VISIBLE);
|
||||
appbar.setExpanded(true);
|
||||
progressDialog.dismiss();
|
||||
} else {
|
||||
|
|
@ -791,11 +797,10 @@ public class MainActivity extends AppCompatActivity {
|
|||
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
|
||||
//activity.startActivity(new Intent(activity, RemoteCanvasActivity.class));
|
||||
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
|
||||
try {
|
||||
TermuxX11.main(new String[]{":0"});
|
||||
} catch (ErrnoException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
extViewerLayout.setVisibility(View.VISIBLE);
|
||||
appbar.setExpanded(true);
|
||||
progressDialog.dismiss();
|
||||
|
||||
Intent x11Intent = new Intent();
|
||||
x11Intent.setClassName("com.termux.x11", "com.termux.x11.MainActivity");
|
||||
|
|
@ -806,6 +811,12 @@ public class MainActivity extends AppCompatActivity {
|
|||
} catch (ActivityNotFoundException e) {
|
||||
Log.e("LaunchActivity", "Activity not found: " + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
TermuxX11.main(new String[]{":0"});
|
||||
} catch (ErrnoException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ import android.app.NotificationManager;
|
|||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
|
@ -26,6 +28,9 @@ public class MainService extends Service {
|
|||
private String TAG = "MainService";
|
||||
public static MainService service;
|
||||
|
||||
private PowerManager.WakeLock wakeLock;
|
||||
private WifiManager.WifiLock wifiLock;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
|
@ -44,11 +49,19 @@ public class MainService extends Service {
|
|||
.addAction(R.drawable.round_logout_24, "Stop", pStopSelf)
|
||||
.build();
|
||||
|
||||
|
||||
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Vectras::MyWakeLockTag");
|
||||
wakeLock.acquire();
|
||||
|
||||
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
|
||||
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "Vectras::MyWifiLockTag");
|
||||
wifiLock.acquire();
|
||||
|
||||
if (env != null) {
|
||||
if (service != null) {
|
||||
String filesDir = MainActivity.activity.getFilesDir().getAbsolutePath();
|
||||
Terminal vterm = new Terminal(this);
|
||||
//vterm.executeShellCommand("chmod 770 /run/pulse -R");
|
||||
vterm.executeShellCommand("awesome &", false, MainActivity.activity);
|
||||
//vterm.executeShellCommand("pulseaudio --system --disallow-exit --disallow-module-loading --daemonize --log-level=debug --log-time=1");
|
||||
vterm.executeShellCommand(env, true, MainActivity.activity);
|
||||
}
|
||||
|
|
@ -89,6 +102,21 @@ public class MainService extends Service {
|
|||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
// Release the WakeLock if it is held
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
}
|
||||
|
||||
// Release the WifiLock if it is held
|
||||
if (wifiLock != null && wifiLock.isHeld()) {
|
||||
wifiLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package com.vectras.vm;
|
||||
|
||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
import static com.vectras.vm.utils.UIUtils.UIAlert;
|
||||
|
||||
|
|
@ -10,20 +13,26 @@ import android.content.Context;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.Settings;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
|
@ -66,6 +75,9 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
|
||||
tarPath = getExternalFilesDir("data") + "/data.tar.gz";
|
||||
|
||||
if (!checkPermission())
|
||||
requestPermission();
|
||||
|
||||
alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create();
|
||||
alertDialog.setTitle("BOOTSTRAP REQUIRED!");
|
||||
alertDialog.setMessage("U can choose between auto download and setup or manual setup by choosing bootstrap file.");
|
||||
|
|
@ -97,9 +109,53 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
setupVectras();
|
||||
} else {
|
||||
alertDialog.show();
|
||||
|
||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
|
||||
showDisableBatteryOptimizationDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] storage_permissions = {
|
||||
WRITE_EXTERNAL_STORAGE,
|
||||
READ_EXTERNAL_STORAGE
|
||||
};
|
||||
|
||||
private boolean checkPermission() {
|
||||
if (SDK_INT >= Build.VERSION_CODES.R) {
|
||||
return Environment.isExternalStorageManager();
|
||||
} else {
|
||||
int result = ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE);
|
||||
int result1 = ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE);
|
||||
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
private void requestPermission() {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
permissions(),
|
||||
1002);
|
||||
}
|
||||
|
||||
public static String[] permissions() {
|
||||
String[] p;
|
||||
p = storage_permissions;
|
||||
return p;
|
||||
}
|
||||
|
||||
private void showDisableBatteryOptimizationDialog() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("Disable Battery Optimization")
|
||||
.setMessage("To ensure the app functions correctly, please disable battery optimization for this app.")
|
||||
.setCancelable(false)
|
||||
.setPositiveButton("Disable", (dialog, which) -> {
|
||||
Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
|
||||
startActivity(intent);
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.btnInstall) {
|
||||
|
|
@ -352,7 +408,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
" apk update;" +
|
||||
" apk add tar libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
|
||||
" libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev rdma-core" +
|
||||
" libusb ncurses-libs curl libnfs sdl2 gtk+3.0 fuse libpulse libseccomp jack pipewire liburing xkeyboard-config;" +
|
||||
" libusb ncurses-libs curl libnfs sdl2 gtk+3.0 fuse libpulse libseccomp jack pipewire liburing awesome lxterminal font-terminus xkeyboard-config;" +
|
||||
" tar -xzvf " + tarPath + " -C /;" +
|
||||
" rm " + tarPath + ";" +
|
||||
" mkdir -p ~/.vnc && echo -e \"555555\\n555555\" | vncpasswd -f > ~/.vnc/passwd && chmod 0600 ~/.vnc/passwd;" +
|
||||
|
|
@ -371,7 +427,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
File selectedFilePath = new File(getPath(content_describer));
|
||||
ProgressBar loading = progressBar;
|
||||
String abi = Build.SUPPORTED_ABIS[0];
|
||||
if (selectedFilePath.toString().endsWith(abi+".tar.gz")) {
|
||||
if (selectedFilePath.toString().endsWith(abi + ".tar.gz")) {
|
||||
loading.setVisibility(View.VISIBLE);
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
|
|
@ -423,6 +479,14 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
alertDialog.show();
|
||||
UIAlert(activity, "INVALID FILE", "please select vectras-vm-" + abi + ".tar.gz file");
|
||||
}
|
||||
|
||||
} else if (requestCode == 1002 && resultCode == RESULT_OK) {
|
||||
|
||||
if (!checkPermission()) {
|
||||
requestPermission();
|
||||
Toast.makeText(this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
} else
|
||||
alertDialog.show();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
|
|||
SharedPreferences prefs = getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE);
|
||||
|
||||
try {
|
||||
new Handler().postDelayed(activity, 3000);
|
||||
new Handler().postDelayed(activity, 1000);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}/*
|
||||
|
|
@ -67,8 +67,6 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
|
|||
} else {
|
||||
}
|
||||
*/
|
||||
if (!checkPermission())
|
||||
requestPermission();
|
||||
MainSettingsManager.setOrientationSetting(activity, 1);
|
||||
|
||||
setupFiles();
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@ public class StartVM {
|
|||
|
||||
ArrayList<String> params = new ArrayList<>(Arrays.asList(qemu));
|
||||
|
||||
params.add("awesome;");
|
||||
|
||||
if (MainSettingsManager.getArch(activity).equals("I386"))
|
||||
params.add("qemu-system-i386");
|
||||
else if (MainSettingsManager.getArch(activity).equals("X86_64"))
|
||||
|
|
|
|||
|
|
@ -24,178 +24,107 @@ import com.vectras.qemu.MainSettingsManager;
|
|||
import com.vectras.qemu.MainVNCActivity;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.VectrasApp;
|
||||
|
||||
public class Terminal {
|
||||
private static final String TAG = "Vterm";
|
||||
private Context context;
|
||||
private String user = "root";
|
||||
|
||||
public static Process qemuProcess;
|
||||
private Process qemuProcess;
|
||||
private BufferedWriter commandWriter;
|
||||
public static String DISPLAY = ":0";
|
||||
|
||||
public Terminal(Context context) {
|
||||
this.context = context;
|
||||
startQemuProcess();
|
||||
}
|
||||
|
||||
|
||||
private String getLocalIpAddress() {
|
||||
private void startQemuProcess() {
|
||||
try {
|
||||
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
|
||||
NetworkInterface intf = en.nextElement();
|
||||
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
|
||||
InetAddress inetAddress = enumIpAddr.nextElement();
|
||||
if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) {
|
||||
return inetAddress.getHostAddress().toString();
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
String filesDir = context.getFilesDir().getAbsolutePath();
|
||||
String nativeLibDir = context.getApplicationInfo().nativeLibraryDir;
|
||||
|
||||
File tmpDir = new File(context.getFilesDir(), "tmp");
|
||||
|
||||
processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath());
|
||||
processBuilder.environment().put("PROOT_LOADER", nativeLibDir + "/libproot-loader.so");
|
||||
processBuilder.environment().put("PROOT_LOADER_32", nativeLibDir + "/libproot-loader32.so");
|
||||
|
||||
processBuilder.environment().put("HOME", "/root");
|
||||
processBuilder.environment().put("USER", user);
|
||||
processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
|
||||
processBuilder.environment().put("TERM", "xterm-256color");
|
||||
processBuilder.environment().put("TMPDIR", tmpDir.getAbsolutePath());
|
||||
processBuilder.environment().put("SHELL", "/bin/sh");
|
||||
processBuilder.environment().put("DISPLAY", DISPLAY);
|
||||
|
||||
String[] prootCommand = {
|
||||
nativeLibDir + "/libproot.so",
|
||||
"--kill-on-exit",
|
||||
"--link2symlink",
|
||||
"-0",
|
||||
"-r", filesDir + "/distro",
|
||||
"-b", "/dev",
|
||||
"-b", "/proc",
|
||||
"-b", "/sys",
|
||||
"-b", "/sdcard",
|
||||
"-b", "/storage",
|
||||
"-b", "/data",
|
||||
"-b", filesDir + "/distro/root:/dev/shm",
|
||||
"-b", tmpDir.getAbsolutePath() + ":/tmp",
|
||||
"-w", "/root",
|
||||
"/usr/bin/env", "-i",
|
||||
"HOME=/root",
|
||||
"DISPLAY=" + DISPLAY,
|
||||
"/bin/sh",
|
||||
"--login"
|
||||
};
|
||||
|
||||
processBuilder.command(prootCommand);
|
||||
qemuProcess = processBuilder.start();
|
||||
commandWriter = new BufferedWriter(new OutputStreamWriter(qemuProcess.getOutputStream()));
|
||||
|
||||
// Thread to read the output from the process
|
||||
new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(qemuProcess.getInputStream()));
|
||||
BufferedReader errorReader = new BufferedReader(new InputStreamReader(qemuProcess.getErrorStream()))) {
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
Log.d(TAG, line);
|
||||
com.vectras.vm.logger.VectrasStatus.logError("<font color='yellow'>VTERM: >" + line + "</font>");
|
||||
}
|
||||
while ((line = errorReader.readLine()) != null) {
|
||||
Log.w(TAG, line);
|
||||
com.vectras.vm.logger.VectrasStatus.logError("<font color='red'>VTERM ERROR: >" + line + "</font>");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error reading from qemuProcess", e);
|
||||
}
|
||||
}
|
||||
} catch (SocketException ex) {
|
||||
ex.printStackTrace();
|
||||
}).start();
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to start qemuProcess", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void showDialog(String message, Activity activity) {
|
||||
AlertDialog dialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme)
|
||||
.setTitle("Execution Result")
|
||||
.setMessage(message)
|
||||
.setPositiveButton("OK", (dialogInterface, i) -> dialogInterface.dismiss())
|
||||
.create();
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
// Method to execute the shell command
|
||||
public void executeShellCommand(String userCommand, boolean showResultDialog, Activity dialogActivity) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
StringBuilder errors = new StringBuilder();
|
||||
Log.d(TAG, userCommand);
|
||||
com.vectras.vm.logger.VectrasStatus.logError("<font color='yellow'>VTERM: >" + userCommand + "</font>");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// Setup the qemuProcess builder to start PRoot with environmental variables and commands
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
|
||||
// Adjust these environment variables as necessary for your app
|
||||
String filesDir = context.getFilesDir().getAbsolutePath();
|
||||
String nativeLibDir = context.getApplicationInfo().nativeLibraryDir;
|
||||
|
||||
File tmpDir = new File(context.getFilesDir(), "tmp");
|
||||
|
||||
// Setup environment for the PRoot qemuProcess
|
||||
processBuilder.environment().put("PROOT_TMP_DIR", tmpDir.getAbsolutePath());
|
||||
processBuilder.environment().put("PROOT_LOADER", nativeLibDir + "/libproot-loader.so");
|
||||
processBuilder.environment().put("PROOT_LOADER_32", nativeLibDir + "/libproot-loader32.so");
|
||||
|
||||
processBuilder.environment().put("HOME", "/root");
|
||||
processBuilder.environment().put("USER", user);
|
||||
processBuilder.environment().put("PATH", "/bin:/usr/bin:/sbin:/usr/sbin");
|
||||
processBuilder.environment().put("TERM", "xterm-256color");
|
||||
processBuilder.environment().put("TMPDIR", tmpDir.getAbsolutePath());
|
||||
processBuilder.environment().put("SHELL", "/bin/sh");
|
||||
processBuilder.environment().put("DISPLAY", DISPLAY);
|
||||
|
||||
String[] prootCommand = {
|
||||
nativeLibDir + "/libproot.so", // PRoot binary path
|
||||
"--kill-on-exit",
|
||||
"--link2symlink",
|
||||
"-0",
|
||||
"-r", filesDir + "/distro", // Path to the rootfs
|
||||
"-b", "/dev",
|
||||
"-b", "/proc",
|
||||
"-b", "/sys",
|
||||
"-b", "/sdcard",
|
||||
"-b", "/storage",
|
||||
"-b", "/data",
|
||||
"-w", "/root",
|
||||
"/usr/bin/env", "-i",
|
||||
"HOME=/root",
|
||||
"DISPLAY="+DISPLAY,
|
||||
"/bin/sh",
|
||||
"--login"// The shell to execute inside PRoot
|
||||
};
|
||||
|
||||
processBuilder.command(prootCommand);
|
||||
qemuProcess = processBuilder.start();
|
||||
// Get the input and output streams of the qemuProcess
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(qemuProcess.getOutputStream()));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(qemuProcess.getInputStream()));
|
||||
BufferedReader errorReader = new BufferedReader(new InputStreamReader(qemuProcess.getErrorStream()));
|
||||
|
||||
// Send user command to PRoot
|
||||
writer.write(userCommand);
|
||||
writer.newLine();
|
||||
writer.flush();
|
||||
writer.close();
|
||||
|
||||
// Read the input stream for the output of the command
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
Log.d(TAG, line);
|
||||
com.vectras.vm.logger.VectrasStatus.logError("<font color='yellow'>VTERM: >" + line + "</font>");
|
||||
output.append(line).append("\n");
|
||||
if (commandWriter != null) {
|
||||
commandWriter.write(userCommand);
|
||||
commandWriter.newLine();
|
||||
commandWriter.flush();
|
||||
}
|
||||
|
||||
// Read any errors from the error stream
|
||||
while ((line = errorReader.readLine()) != null) {
|
||||
Log.w(TAG, line);
|
||||
com.vectras.vm.logger.VectrasStatus.logError("<font color='red'>VTERM ERROR: >" + line + "</font>");
|
||||
output.append(line).append("\n");
|
||||
}
|
||||
|
||||
// Clean up
|
||||
reader.close();
|
||||
errorReader.close();
|
||||
|
||||
int exitCode = qemuProcess.waitFor(); // Wait for the process to finish
|
||||
if (exitCode == 0) {
|
||||
output.append("Execution finished successfully.\n");
|
||||
output.append(reader.readLine()).append("\n");
|
||||
Log.i(TAG, reader.readLine());
|
||||
} else {
|
||||
output.append("Execution finished with exit code: ").append(exitCode).append("\n");
|
||||
output.append(reader.readLine()).append("\n");
|
||||
Log.i(TAG, reader.readLine());
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
output.append(e.getMessage());
|
||||
errors.append(Log.getStackTraceString(e));
|
||||
MainActivity.clearNotifications();
|
||||
} finally {
|
||||
// Switch to main thread after execution
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
// If showResultDialog is enabled, show the dialog with the result or errors
|
||||
if (showResultDialog) {
|
||||
String finalOutput = output.toString();
|
||||
String finalErrors = errors.toString();
|
||||
// bcuz there is dumb users bruh
|
||||
showDialog(finalOutput.isEmpty() ? finalErrors : finalOutput.replace("read interrupted", "Done!"), dialogActivity);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error writing to qemuProcess", e);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private boolean checkInstallation() {
|
||||
String filesDir = context.getFilesDir().getAbsolutePath();
|
||||
File distro = new File(filesDir, "distro");
|
||||
return distro.exists();
|
||||
}
|
||||
|
||||
public static void killQemuProcess() {
|
||||
if (qemuProcess != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
qemuProcess.destroyForcibly();
|
||||
else
|
||||
qemuProcess.destroy();
|
||||
if (!MainSettingsManager.getVncExternal(MainActivity.activity)) {
|
||||
MainVNCActivity.activity.finish();
|
||||
MainVNCActivity.started = false;
|
||||
}
|
||||
qemuProcess = null; // Set it to null after destroying it
|
||||
Log.d(TAG, "QEMU process destroyed.");
|
||||
} else {
|
||||
Log.d(TAG, "QEMU process was null.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue