Vectras-VM-Android/app/src/main/java/com/vectras/vm/VMManager.java
An Bui fa7df64ceb v2.9.5.13-3dfx
- Faster virtual machine boot time.
- Force VNC refresh is on by default.
- Added exporter that will show error message if no folder to save cvbi file can be created.
- New virtual machine startup dialog interface.
- Added Quick start toggle.
- Fixed bug where System Monitor sometimes did not show correct status of Qemu and VNC Server.
- Text color of dialog buttons will be brighter if in dark mode.
- Improved ability to determine if a virtual machine is running.
- Qemu will no longer be forced to kill explicitly so it can perform some actions before dying to avoid data corruption
- Some changes to the interface in the drawer.
- External VNC Server notification dialog will only appear when using VNC instead of X11.
2025-10-06 17:21:57 +07:00

1215 lines
57 KiB
Java

package com.vectras.vm;
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
import static com.vectras.vm.utils.FileUtils.isFileExists;
import android.androidVNC.AbstractScaling;
import android.androidVNC.VncCanvasActivity;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import com.vectras.qemu.Config;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.qemu.MainVNCActivity;
import com.vectras.qemu.VNCConfig;
import com.vectras.qemu.utils.QmpClient;
import com.vectras.vm.home.HomeActivity;
import com.vectras.vm.settings.VNCSettingsActivity;
import com.vectras.vm.utils.DialogUtils;
import com.vectras.vm.utils.FileUtils;
import com.vectras.vm.utils.JSONUtils;
import com.vectras.vm.utils.UIUtils;
import com.vectras.vterm.Terminal;
import org.jetbrains.annotations.Contract;
import org.json.JSONArray;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;
import java.util.Random;
public class VMManager {
public static final String TAG = "VMManager";
public static HashMap<String, Object> mapForCreateNewVM = new HashMap<>();
public static ArrayList<HashMap<String, Object>> listmapForCreateNewVM = new ArrayList<>();
public static ArrayList<HashMap<String, Object>> listmapForRemoveVM = new ArrayList<>();
public static ArrayList<HashMap<String, Object>> listmapForHideVMID = new ArrayList<>();
public static String finalJson = "";
public static String pendingJsonContent = "";
public static String pendingVMID = "";
public static int pendingPosition = 0;
public static String pendingDeviceID = "";
public static int restoredVMs = 0;
public static boolean isKeptSomeFiles = false;
public static boolean isQemuStopedWithError = false;
public static String latestUnsafeCommandReason = "";
public static String lastQemuCommand = "";
public static void createNewVM(String name, String thumbnail, String drive, String arch, String cdrom, String params, String vmID, int port) {
mapForCreateNewVM.clear();
mapForCreateNewVM.put("imgName", name);
mapForCreateNewVM.put("imgIcon", thumbnail);
mapForCreateNewVM.put("imgPath", drive);
mapForCreateNewVM.put("imgCdrom", cdrom);
mapForCreateNewVM.put("imgExtra", params);
mapForCreateNewVM.put("imgArch", arch);
mapForCreateNewVM.put("vmID", vmID);
mapForCreateNewVM.put("qmpPort", port);
listmapForCreateNewVM.clear();
listmapForCreateNewVM = new Gson().fromJson(FileUtils.readAFile(AppConfig.romsdatajson), new TypeToken<ArrayList<HashMap<String, Object>>>(){}.getType());
listmapForCreateNewVM.add(0,mapForCreateNewVM);
finalJson = new Gson().toJson(listmapForCreateNewVM);
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", finalJson);
finalJson = new Gson().toJson(mapForCreateNewVM);
FileUtils.writeToFile(AppConfig.maindirpath + "/roms/" + Objects.requireNonNull(mapForCreateNewVM.get("vmID")), "rom-data.json", finalJson.replace("\\u003d", "="));
FileUtils.writeToFile(AppConfig.maindirpath + "/roms/" + Objects.requireNonNull(mapForCreateNewVM.get("vmID")), "vmID.txt", Objects.requireNonNull(mapForCreateNewVM.get("vmID")).toString());
}
public static void editVM(String name, String thumbnail, String drive, String arch, String cdrom, String params, int position) {
listmapForCreateNewVM.clear();
listmapForCreateNewVM = new Gson().fromJson(FileUtils.readAFile(AppConfig.romsdatajson), new TypeToken<ArrayList<HashMap<String, Object>>>(){}.getType());
mapForCreateNewVM.clear();
mapForCreateNewVM.put("imgName", name);
mapForCreateNewVM.put("imgIcon", thumbnail);
mapForCreateNewVM.put("imgPath", drive);
mapForCreateNewVM.put("imgCdrom", cdrom);
mapForCreateNewVM.put("imgExtra", params);
mapForCreateNewVM.put("imgArch", arch);
if (listmapForCreateNewVM.get(position).containsKey("qmpPort")) {
mapForCreateNewVM.put("qmpPort", listmapForCreateNewVM.get(position).get("qmpPort"));
} else {
mapForCreateNewVM.put("qmpPort", startRandomPort());
}
if (listmapForCreateNewVM.get(position).containsKey("vmID")) {
mapForCreateNewVM.put("vmID", Objects.requireNonNull(listmapForCreateNewVM.get(position).get("vmID")).toString());
} else {
mapForCreateNewVM.put("vmID", idGenerator());
}
listmapForCreateNewVM.set(position,mapForCreateNewVM);
finalJson = new Gson().toJson(listmapForCreateNewVM);
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", finalJson);
finalJson = new Gson().toJson(mapForCreateNewVM);
FileUtils.writeToFile(AppConfig.maindirpath + "/roms/" + Objects.requireNonNull(mapForCreateNewVM.get("vmID")), "rom-data.json", finalJson.replace("\\u003d", "="));
FileUtils.writeToFile(AppConfig.maindirpath + "/roms/" + Objects.requireNonNull(mapForCreateNewVM.get("vmID")), "vmID.txt", Objects.requireNonNull(mapForCreateNewVM.get("vmID")).toString());
}
public static void deleteVMDialog(String _vmName, int _position, Activity _activity) {
pendingPosition = _position;
pendingJsonContent = FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json");
DialogUtils.threeDialog(_activity, _activity.getString(R.string.remove)+ " " + _vmName, _activity.getString(R.string.remove_vm_content), _activity.getString(R.string.remove_and_do_not_keep_files), _activity.getString(R.string.remove_but_keep_files), _activity.getString(R.string.cancel),true, R.drawable.delete_24px, true,
() -> {
isKeptSomeFiles = false;
deleteVM();
removeInRomsDataJson(_activity, _vmName, _position);
},
() -> {
hideVMIDWithPosition();
removeInRomsDataJson(_activity, _vmName, _position);
},
() -> {
},
null);
}
public static void removeInRomsDataJson(Activity _activity, String _vmName, int _position) {
try {
JSONArray jSONArray = new JSONArray(FileUtils.readFromFile(_activity, new File(AppConfig.maindirpath
+ "roms-data.json")));
jSONArray.remove(_position);
Writer output;
File jsonFile = new File(AppConfig.maindirpath + "roms-data" + ".json");
output = new BufferedWriter(new FileWriter(jsonFile));
output.write(jSONArray.toString());
output.close();
} catch (Exception e) {
UIUtils.toastLong(_activity, e.toString());
}
UIUtils.toastLong(_activity, _vmName + _activity.getString(R.string.are_removed_successfully));
HomeActivity.refeshVMListNow();
}
public static String idGenerator() {
String _result = startRamdomVMID();
if (isFileExists(AppConfig.maindirpath + "/roms/" + _result)) {
_result = startRamdomVMID();
}
if (isFileExists(AppConfig.maindirpath + "/roms/" + _result)) {
_result = startRamdomVMID();
}
return _result;
}
@NonNull
public static String startRamdomVMID() {
String addAdb;
Random random = new Random();
int randomAbc = random.nextInt(12);
if (randomAbc == 0) {
addAdb = "a";
} else if (randomAbc == 1) {
addAdb = "b";
} else if (randomAbc == 2) {
addAdb = "c";
} else if (randomAbc == 3) {
addAdb = "d";
} else if (randomAbc == 4) {
addAdb = "e";
} else if (randomAbc == 5) {
addAdb = "f";
} else if (randomAbc == 6) {
addAdb = "g";
} else if (randomAbc == 7) {
addAdb = "h";
} else if (randomAbc == 8) {
addAdb = "i";
} else if (randomAbc == 9) {
addAdb = "j";
} else if (randomAbc == 10) {
addAdb = "k";
} else {
addAdb = "l";
}
return addAdb + (long) (random.nextInt(65535));
}
public static int startRandomPort() {
int _result;
Random _random = new Random();
int _min = 10000;
int _max = 65535;
_result = _random.nextInt(_max - _min + 1) + _min;
if (FileUtils.isFileExists(AppConfig.romsdatajson)) {
if (FileUtils.readAFile(AppConfig.romsdatajson).contains("\"qmpPort\":" + _result)) {
_result = _random.nextInt(_max - _min + 1) + _min;
}
if (FileUtils.readAFile(AppConfig.romsdatajson).contains("\"qmpPort\":" + _result)) {
_result = _random.nextInt(_max - _min + 1) + _min;
}
}
return _result;
}
public static void deleteVM() {
listmapForRemoveVM.clear();
listmapForRemoveVM = new Gson().fromJson(pendingJsonContent, new TypeToken<ArrayList<HashMap<String, Object>>>(){}.getType());
if (listmapForRemoveVM.get(pendingPosition).containsKey("vmID")) {
pendingVMID = Objects.requireNonNull(listmapForRemoveVM.get(pendingPosition).get("vmID")).toString();
FileUtils.deleteDirectory(Config.getCacheDir()+ "/" + pendingVMID);
Log.i("VMManager", "deleteVM: ID obtained: " + pendingVMID);
} else {
Log.e("VMManager", "deleteVM: Cannot get ID.");
return;
}
listmapForRemoveVM.remove(pendingPosition);
finalJson = new Gson().toJson(listmapForRemoveVM);
if (!pendingVMID.isEmpty()) {
int _startRepeat = 0;
String _currentVMIDToScan;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
_currentVMIDToScan = FileUtils.readAFile(_filelist.get(_startRepeat) + "/vmID.txt").replace("\n", "");
if (!_currentVMIDToScan.isEmpty()) {
if (_currentVMIDToScan.equals(pendingVMID)) {
if (!finalJson.contains(_filelist.get(_startRepeat))) {
FileUtils.deleteDirectory(_filelist.get(_startRepeat));
} else {
isKeptSomeFiles = true;
hideVMID(pendingVMID);
}
}
}
}
}
_startRepeat++;
}
}
}
}
public static void hideVMID(@NonNull String _vmID) {
if (!_vmID.isEmpty()) {
int _startRepeat = 0;
String _currentVMIDToScan;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
_currentVMIDToScan = FileUtils.readAFile(_filelist.get(_startRepeat) + "/vmID.txt").replace("\n", "");
if (!_currentVMIDToScan.isEmpty()) {
if (_currentVMIDToScan.equals(_vmID)) {
FileUtils.moveAFile(_filelist.get(_startRepeat) + "/vmID.txt", _filelist.get(_startRepeat) + "/vmID.old.txt");
}
}
}
}
_startRepeat++;
}
}
}
}
public static void hideVMIDWithPosition() {
listmapForHideVMID.clear();
listmapForHideVMID = new Gson().fromJson(pendingJsonContent, new TypeToken<ArrayList<HashMap<String, Object>>>(){}.getType());
if (listmapForHideVMID.get(pendingPosition).containsKey("vmID")) {
pendingVMID = Objects.requireNonNull(listmapForHideVMID.get(pendingPosition).get("vmID")).toString();
} else {
return;
}
if (!pendingVMID.isEmpty()) {
int _startRepeat = 0;
String _currentVMIDToScan;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
_currentVMIDToScan = FileUtils.readAFile(_filelist.get(_startRepeat) + "/vmID.txt").replace("\n", "");
if (!_currentVMIDToScan.isEmpty()) {
if (_currentVMIDToScan.equals(pendingVMID)) {
FileUtils.moveAFile(_filelist.get(_startRepeat) + "/vmID.txt", _filelist.get(_startRepeat) + "/vmID.old.txt");
}
}
}
}
_startRepeat++;
}
}
}
}
public static void cleanUp() {
finalJson = FileUtils.readAFile(AppConfig.romsdatajson);
if (!finalJson.isEmpty()) {
int _startRepeat = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (!isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
if (!finalJson.contains(_filelist.get(_startRepeat))) {
FileUtils.deleteDirectory(_filelist.get(_startRepeat));
}
}
}
_startRepeat++;
}
}
}
}
public static void restoreVMs() {
int _startRepeat = 0;
StringBuilder _resulttemp = new StringBuilder();
StringBuilder _result = new StringBuilder();
restoredVMs = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (!isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
if (isFileExists(_filelist.get(_startRepeat) + "/rom-data.json")) {
if (JSONUtils.isValidFromString(FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"))) {
if (_resulttemp.toString().contains("}")) {
_resulttemp.append(",").append(FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"));
} else {
_resulttemp = new StringBuilder(FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"));
}
if (JSONUtils.isValidFromString(FileUtils.readAFile(AppConfig.maindirpath + "/roms-data.json").replaceAll("]", _resulttemp + "]"))) {
if (_result.toString().contains("}")) {
_result.append(",").append(FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"));
} else {
_result = new StringBuilder(FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"));
}
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.old.txt")) {
enableVMID(FileUtils.readAFile(_filelist.get(_startRepeat) + "/vmID.old.txt"));
} else {
FileUtils.writeToFile(_filelist.get(_startRepeat), "/vmID.txt", VMManager.idGenerator());
}
restoredVMs++;
} else if (JSONUtils.isValidFromString(FileUtils.readAFile(AppConfig.maindirpath + "/roms-data.json").replaceAll("]", "," + _resulttemp + "]"))) {
if (_result.toString().contains("}")) {
_result.append(",").append(FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"));
} else {
_result = new StringBuilder("," + FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json"));
}
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.old.txt")) {
enableVMID(FileUtils.readAFile(_filelist.get(_startRepeat) + "/vmID.old.txt"));
} else {
FileUtils.writeToFile(_filelist.get(_startRepeat), "/vmID.txt", VMManager.idGenerator());
}
restoredVMs++;
} else {
Log.i("CqcmActivity", FileUtils.readAFile(AppConfig.maindirpath + "/roms-data.json").replaceAll("]", _resulttemp + "]"));
}
}
}
}
_startRepeat++;
if (_startRepeat == _filelist.size()) {
if (_result.length() > 0) {
if (JSONUtils.isValidFromString("[" + _result + "]")) {
if (isFileExists(AppConfig.romsdatajson)) {
if (JSONUtils.isValidFromFile(AppConfig.romsdatajson)) {
String _JSONcontent = FileUtils.readAFile(AppConfig.romsdatajson);
String _JSONcontentnew = _JSONcontent.replaceAll("]", _result + "]");
if (JSONUtils.isValidFromString(_JSONcontentnew)) {
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", _JSONcontentnew);
} else {
restoredVMs = 0;
}
} else {
restoredVMs = 0;
}
} else {
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[" + _result + "]");
}
} else {
restoredVMs = 0;
}
} else {
restoredVMs = 0;
}
}
}
}
}
}
public static void startFixRomsDataJson() {
int _startRepeat = 0;
String tempRomData;
JsonArray arr = new JsonArray();
restoredVMs = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
if (isFileExists(_filelist.get(_startRepeat) + "/rom-data.json")) {
tempRomData = FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json");
if (JSONUtils.isValidFromString(tempRomData)) {
arr.add(JsonParser.parseString(tempRomData));
restoredVMs++;
}
}
}
_startRepeat++;
if (_startRepeat == _filelist.size()) {
if (restoredVMs > 0) {
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", arr.toString());
}
}
}
}
}
}
public static void enableVMID(@NonNull String _vmID) {
if (_vmID.isEmpty())
return;
int _startRepeat = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.old.txt")) {
if (FileUtils.readAFile(_filelist.get(_startRepeat) + "/vmID.old.txt").equals(_vmID)) {
FileUtils.moveAFile(_filelist.get(_startRepeat) + "/vmID.old.txt", _filelist.get(_startRepeat) + "/vmID.txt");
}
}
}
_startRepeat++;
}
}
}
public static void movetoRecycleBin() {
File vDir = new File(AppConfig.recyclebin);
if (!vDir.exists()) {
if (!vDir.mkdirs()) {
return;
}
}
finalJson = FileUtils.readAFile(AppConfig.romsdatajson);
if (!finalJson.isEmpty()) {
int _startRepeat = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (!finalJson.contains(Objects.requireNonNull(Uri.parse(_filelist.get(_startRepeat)).getLastPathSegment()))) {
FileUtils.moveAFile(_filelist.get(_startRepeat), AppConfig.recyclebin + Uri.parse(_filelist.get(_startRepeat)).getLastPathSegment());
}
}
_startRepeat++;
}
}
}
}
public static String quickScanDiskFileInFolder(@NonNull String _foderpath) {
if (!_foderpath.isEmpty()) {
int _startRepeat = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(_foderpath, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isADiskFile(_filelist.get(_startRepeat))) {
return _filelist.get(_startRepeat);
}
}
_startRepeat++;
}
}
}
return "";
}
public static boolean isADiskFile (@NonNull String _filepath) {
if (_filepath.contains(".")) {
String _getFileName = Objects.requireNonNull(Uri.parse(_filepath).getLastPathSegment()).toLowerCase();
String _getFileFormat = _getFileName.substring(_getFileName.lastIndexOf(".") + 1);
return "qcow2,img,vhd,vhdx,vdi,qcow,vmdk,vpc".contains(_getFileFormat);
}
return false;
}
public static String quickScanISOFileInFolder(@NonNull String _foderpath) {
if (!_foderpath.isEmpty()) {
int _startRepeat = 0;
ArrayList<String> _filelist = new ArrayList<>();
FileUtils.getAListOfAllFilesAndFoldersInADirectory(_foderpath, _filelist);
if (!_filelist.isEmpty()) {
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
if (_startRepeat < _filelist.size()) {
if (isAISOFile(_filelist.get(_startRepeat))) {
return _filelist.get(_startRepeat);
}
}
_startRepeat++;
}
}
}
return "";
}
public static boolean isAISOFile (@NonNull String _filepath) {
if (_filepath.contains(".")) {
String _getFileName = Objects.requireNonNull(Uri.parse(_filepath).getLastPathSegment()).toLowerCase();
String _getFileFormat = _getFileName.substring(_getFileName.lastIndexOf(".") + 1);
return "iso".contains(_getFileFormat);
}
return false;
}
public static void setArch(@NonNull String _arch, Activity _activity) {
switch (_arch) {
case "I386":
MainSettingsManager.setArch(_activity, "I386");
break;
case "ARM64":
MainSettingsManager.setArch(_activity, "ARM64");
break;
case "PPC":
MainSettingsManager.setArch(_activity, "PPC");
break;
default:
MainSettingsManager.setArch(_activity, "X86_64");
break;
}
}
public static boolean isExecutedCommandError(@NonNull String _command, String _result, Activity _activity) {
if (!_command.contains("qemu-system")) {
isQemuStopedWithError = false;
return false;
}
if (_command.contains("qemu-system") && _result.contains("Killed")) {
isQemuStopedWithError = true;
return true;
}
//Error code: PROOT_IS_MISSING_0
if (_result.contains("proot\": error=2,")) {
DialogUtils.twoDialog(_activity, _activity.getResources().getString(R.string.problem_has_been_detected), _activity.getResources().getString(R.string.error_PROOT_IS_MISSING_0), _activity.getString(R.string.continuetext), _activity.getString(R.string.cancel), true, R.drawable.build_24px, true,
() -> {
HomeActivity.isActivate = false;
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/data");
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/distro");
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/usr");
Intent intent = new Intent();
intent.setClass(_activity, SplashActivity.class);
_activity.startActivity(intent);
_activity.finish();
},
null, null);
isQemuStopedWithError = true;
return true;
} else if (_result.contains(") exists") && _result.contains("drive with bus")) {
//Error code: DRIVE_INDEX_0_EXISTS
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_DRIVE_INDEX_0_EXISTS) + "\n\n" + _result, _activity.getString(R.string.ok),true, R.drawable.hard_drive_24px, true,null, null);
isQemuStopedWithError = true;
return true;
} else if (_result.contains("gtk initialization failed") || _result.contains("x11 not available")) {
//Error code: X11_NOT_AVAILABLE
DialogUtils.twoDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_X11_NOT_AVAILABLE), _activity.getString(R.string.continuetext), _activity.getString(R.string.cancel), true, R.drawable.cast_24px, true,
() -> {
MainSettingsManager.setVmUi(_activity, "VNC");
DialogUtils.oneDialog(_activity, _activity.getString(R.string.done), _activity.getString(R.string.switched_to_VNC), _activity.getString(R.string.ok),true, R.drawable.check_24px, true,null, null);
},
null, null);
isQemuStopedWithError = true;
return true;
} else if (_result.contains("No such file or directory")) {
//Error code: NO_SUCH_FILE_OR_DIRECTORY
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_NO_SUCH_FILE_OR_DIRECTORY) + "\n\n" + _result, _activity.getString(R.string.ok),true, R.drawable.file_copy_24px, true,null, null);
_activity.stopService(new Intent(_activity, MainService.class));
isQemuStopedWithError = true;
return true;
} else if (_result.contains("another process using")) {
//Error code: ANOTHER_PROCESS_USING_IMAGE
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_ANOTHER_PROCESS_USING_IMAGE) + "\n\n" + _result, _activity.getString(R.string.ok),true, R.drawable.file_copy_24px, true,null, null);
_activity.stopService(new Intent(_activity, MainService.class));
isQemuStopedWithError = true;
return true;
} else if (_command.contains("qemu-system") && _result.contains("qemu-system")) {
//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, _activity.getString(R.string.ok),true, R.drawable.error_96px, true,null, null);
_activity.stopService(new Intent(_activity, MainService.class));
isQemuStopedWithError = true;
return true;
} else {
isQemuStopedWithError = false;
return false;
}
}
public static boolean isRomsDataJsonValid(Boolean _needfix, Activity _context) {
if (isFileExists(AppConfig.romsdatajson)) {
if (!JSONUtils.isValidFromFile(AppConfig.romsdatajson)) {
if (_needfix) {
DialogUtils.twoDialog(_context, _context.getString(R.string.problem_has_been_detected), _context.getString(R.string.need_fix_json_before_create), _context.getString(R.string.continuetext), _context.getString(R.string.cancel), true, R.drawable.build_24px, true,
() -> {
FileUtils.moveAFile(AppConfig.maindirpath + "roms-data.json", AppConfig.maindirpath + "roms-data.old.json");
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[]");
startFixRomsDataJson();
fixRomsDataJsonResult(_context);
},
null, null);
}
return false;
} else {
return true;
}
} else {
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[]");
return true;
}
}
public static void fixRomsDataJsonResult(Activity _context) {
if (restoredVMs == 0) {
DialogUtils.oneDialog(_context, _context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_unsuccessfully), _context.getString(R.string.ok),true, R.drawable.error_96px, true,null, null);
} else {
DialogUtils.oneDialog(_context, _context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_successfully), _context.getString(R.string.ok),true, R.drawable.check_24px, true,null, null);
}
HomeActivity.refeshVMListNow();
movetoRecycleBin();
}
public static boolean isthiscommandsafe(@NonNull String _command, Context _context) {
if (_command.startsWith("qemu")) {
if (!_command.contains("&")) {
if (!_command.contains("\n")) {
if (!_command.contains(";")) {
if (!_command.contains("|")) {
return true;
} else {
latestUnsafeCommandReason = _context.getString(R.string.command_are_not_allowed_to_contain_vertical_bars);
}
} else {
latestUnsafeCommandReason = _context.getString(R.string.command_are_not_allowed_to_contain_semicolons);
}
} else {
latestUnsafeCommandReason = _context.getString(R.string.command_are_not_allowed_to_contain_multiple_lines);
}
} else {
latestUnsafeCommandReason = _context.getString(R.string.command_are_not_allowed_to_contain_amp);
}
} else {
latestUnsafeCommandReason = _context.getString(R.string.not_the_command_to_run_qemu);
}
return false;
}
public static boolean isthiscommandsafeimg(@NonNull String _command, Context _context) {
if (!_command.contains("qcow2")) {
String _getsize = _command.substring(_command.lastIndexOf(" ") + 1);
if (_getsize.toLowerCase().endsWith("t") || _getsize.toLowerCase().endsWith("p") || _getsize.toLowerCase().endsWith("e")) {
latestUnsafeCommandReason = _context.getString(R.string.size_too_large_try_qcow2_format);
return false;
}
if (_getsize.toLowerCase().endsWith("g")) {
if (_getsize.length() <= 2) {
return true;
} else {
latestUnsafeCommandReason = _context.getString(R.string.size_too_large_try_qcow2_format);
return false;
}
}
if (_getsize.toLowerCase().endsWith("m")) {
if (_getsize.length() <= 4) {
return true;
} else {
latestUnsafeCommandReason = _context.getString(R.string.size_too_large_try_qcow2_format);
return false;
}
}
if (_getsize.toLowerCase().endsWith("k")) {
if (_getsize.length() <= 8) {
return true;
} else {
latestUnsafeCommandReason = _context.getString(R.string.size_too_large_try_qcow2_format);
return false;
}
}
}
return true;
}
public static boolean isVMRunning(Activity activity, String vmID) {
String result = Terminal.executeShellCommandWithResult("ps -e", activity);
if (result.contains(Config.getCacheDir() + "/" + vmID + "/qmpsocket")) {
Log.d("VMManager.isThisVMRunning", "Yes");
return true;
} else {
Log.d("VMManager.isThisVMRunning", "No");
return false;
}
}
public static boolean isQemuRunning(Activity activity) {
Terminal vterm = new Terminal(activity);
vterm.executeShellCommand2("ps -e", false, activity);
if (AppConfig.temporaryLastedTerminalOutput.contains("qemu-system")) {
Log.d("VMManager.isQemuRunning", "Yes");
return true;
} else {
Log.d("VMManager.isQemuRunning", "No");
return false;
}
}
public static boolean isHaveADisk(String env) {
return env.contains("-drive") || env.contains("-hda") || env.contains("-hdb") || env.contains("-cdrom") || env.contains("-fda") || env.contains("-fdb");
}
public static void setIconWithName(ImageView imageview, String name) {
String itemName = name.toLowerCase();
if (itemName.contains("linux") || itemName.contains("ubuntu") || itemName.contains("debian") || itemName.contains("arch") || itemName.contains("kali")) {
imageview.setImageResource(R.drawable.linux);
} else if (itemName.contains("windows")) {
imageview.setImageResource(R.drawable.windows);
} else if (itemName.contains("macos") || itemName.contains("mac os")) {
imageview.setImageResource(R.drawable.macos);
} else if (itemName.contains("android")) {
imageview.setImageResource(R.drawable.android);
} else {
imageview.setImageResource(R.drawable.ic_computer_180dp_with_padding);
}
}
public static void requestKillAllQemuProcess(Activity activity, Runnable runnable) {
DialogUtils.twoDialog(activity, activity.getString(R.string.do_you_want_to_kill_all_qemu_processes), activity.getString(R.string.all_running_vms_will_be_forcibly_shut_down), activity.getString(R.string.kill_all), activity.getString(R.string.cancel), true, R.drawable.power_settings_new_24px, true,
() -> {
killallqemuprocesses(activity);
if (runnable != null) runnable.run();
}, null, null);
}
public static void killcurrentqemuprocess(Activity activity) {
Terminal vterm = new Terminal(activity);
String env = "killall -15 ";
switch (MainSettingsManager.getArch(activity)) {
case "ARM64":
env += "qemu-system-aarch64";
break;
case "PPC":
env += "qemu-system-ppc";
break;
case "I386":
env += "qemu-system-i386";
break;
default:
env += "qemu-system-x86_64";
break;
}
vterm.executeShellCommand2(env, false, null);
}
public static void killallqemuprocesses(Context context) {
Terminal vterm = new Terminal(context);
vterm.executeShellCommand2("killall -15 qemu-system-i386", false, null);
vterm.executeShellCommand2("killall -15 qemu-system-x86_64", false, null);
vterm.executeShellCommand2("killall -15 qemu-system-aarch64", false, null);
vterm.executeShellCommand2("killall -15 qemu-system-ppc", false, null);
}
public static void shutdownCurrentVM() {
QmpClient.sendCommand("{ \"execute\": \"quit\" }");
}
public static void resetCurrentVM() {
QmpClient.sendCommand("{ \"execute\": \"system_reset\" }");
}
public static void showChangeRemovableDevicesDialog(Activity _activity, VncCanvasActivity vncCanvasActivity) {
String allDevice = getAllDevicesInQemu();
View _view = LayoutInflater.from(_activity).inflate(R.layout.dialog_change_removable_devices, null);
AlertDialog _dialog = new MaterialAlertDialogBuilder(_activity, R.style.CenteredDialogTheme)
.setView(_view)
.create();
if (allDevice != null && (allDevice.contains("ide1-cd0")
|| allDevice.contains("ide2-cd0")
|| allDevice.contains("floppy0")
|| allDevice.contains("floppy1")
|| allDevice.contains("sd0"))) {
if (allDevice.contains("ide1-cd0")
|| allDevice.contains("ide2-cd0")) {
_view.findViewById(R.id.ln_cdrom).setOnClickListener(v -> {
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
_activity.startActivityForResult(intent, 120);
_dialog.dismiss();
});
_view.findViewById(R.id.iv_ejectcdrom).setOnClickListener(v -> {
ejectCDROM(_activity);
_dialog.dismiss();
});
} else {
_view.findViewById(R.id.ln_cdrom).setVisibility(View.GONE);
}
if (allDevice.contains("floppy0")) {
_view.findViewById(R.id.ln_fda).setOnClickListener(v -> {
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
_activity.startActivityForResult(intent, 889);
_dialog.dismiss();
});
_view.findViewById(R.id.iv_ejectfda).setOnClickListener(v -> {
ejectFloppyDriveA(_activity);
_dialog.dismiss();
});
if (!allDevice.contains("floppy1")) {
TextView tvFda = _view.findViewById(R.id.tv_fda);
tvFda.setText(R.string.floppy_drive);
}
} else {
_view.findViewById(R.id.ln_fda).setVisibility(View.GONE);
}
if (allDevice.contains("floppy1")) {
_view.findViewById(R.id.ln_fdb).setOnClickListener(v -> {
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
_activity.startActivityForResult(intent, 13335);
_dialog.dismiss();
});
_view.findViewById(R.id.iv_ejectfdb).setOnClickListener(v -> {
ejectFloppyDriveB(_activity);
_dialog.dismiss();
});
if (!allDevice.contains("floppy0")) {
TextView tvFdb = _view.findViewById(R.id.tv_fdb);
tvFdb.setText(R.string.floppy_drive);
}
} else {
_view.findViewById(R.id.ln_fdb).setVisibility(View.GONE);
}
if (allDevice.contains("sd0")) {
_view.findViewById(R.id.ln_sd).setOnClickListener(v -> {
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
_activity.startActivityForResult(intent, 32);
_dialog.dismiss();
});
_view.findViewById(R.id.iv_ejectsd).setOnClickListener(v -> {
ejectSDCard(_activity);
_dialog.dismiss();
});
} else {
_view.findViewById(R.id.ln_sd).setVisibility(View.GONE);
}
_view.findViewById(R.id.ln_otherdevice).setOnClickListener(v -> {
showChangeRemovableDevicesWithIDDialog(_activity);
_dialog.dismiss();
});
} else {
TextView tvFdb = _view.findViewById(R.id.tv_otherdevice);
tvFdb.setText(R.string.change_or_eject_a_device);
_view.findViewById(R.id.ln_cdrom).setVisibility(View.GONE);
_view.findViewById(R.id.ln_fda).setVisibility(View.GONE);
_view.findViewById(R.id.ln_fdb).setVisibility(View.GONE);
_view.findViewById(R.id.ln_sd).setVisibility(View.GONE);
}
if (vncCanvasActivity != null) {
_view.findViewById(R.id.ln_mouse).setOnClickListener(v -> {
MainVNCActivity.activity.onMouseMode();
_dialog.dismiss();
});
_view.findViewById(R.id.ln_settings).setOnClickListener(v -> {
_activity.startActivity(new Intent(_activity, VNCSettingsActivity.class));
_dialog.dismiss();
});
if (MainSettingsManager.getVNCScaleMode(_activity) == VNCConfig.oneToOne) {
_view.findViewById(R.id.iv_screenOneToOne).setBackgroundResource(R.drawable.dialog_shape_single_button);
} else {
_view.findViewById(R.id.iv_screenFit).setBackgroundResource(R.drawable.dialog_shape_single_button);
}
_view.findViewById(R.id.iv_screenOneToOne).setOnClickListener(v -> {
AbstractScaling.getById(R.id.itemOneToOne)
.setScaleTypeForActivity(vncCanvasActivity);
MainSettingsManager.setVNCScaleMode(_activity, VNCConfig.oneToOne);
_dialog.dismiss();
});
_view.findViewById(R.id.iv_screenFit).setOnClickListener(v -> {
AbstractScaling.getById(R.id.itemFitToScreen)
.setScaleTypeForActivity(vncCanvasActivity);
MainSettingsManager.setVNCScaleMode(_activity, VNCConfig.fitToScreen);
_dialog.dismiss();
});
} else {
_view.findViewById(R.id.ln_user_interface).setVisibility(View.GONE);
}
_dialog.show();
}
public static void showChangeRemovableDevicesWithIDDialog(Activity _activity) {
View _view = LayoutInflater.from(_activity).inflate(R.layout.widget_edittext_dialog, null);
AlertDialog _dialog = new MaterialAlertDialogBuilder(_activity, R.style.CenteredDialogTheme)
.setTitle(_activity.getString(R.string.change_a_removable_device))
.setView(_view)
.create();
EditText _edittext = _view.findViewById(R.id.editText);
TextInputLayout _textInputLayout = _view.findViewById(R.id.textInputLayout);
_textInputLayout.setHint(_activity.getString(R.string.enter_device_id));
_dialog.setButton(DialogInterface.BUTTON_POSITIVE, _activity.getString(R.string.change_disk_file), (dialog, which) -> {
if (!_edittext.getText().toString().isEmpty()) {
pendingDeviceID = _edittext.getText().toString();
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
_activity.startActivityForResult(intent, 1996);
_dialog.dismiss();
} else {
Toast.makeText(_activity, _activity.getString(R.string.you_need_to_enter_the_device_id), Toast.LENGTH_SHORT).show();
}
});
_dialog.setButton(DialogInterface.BUTTON_NEUTRAL, _activity.getString(R.string.eject), (dialog, which) -> {
if (!_edittext.getText().toString().isEmpty()) {
ejectRemovableDevice(_edittext.getText().toString(), _activity);
_dialog.dismiss();
} else {
Toast.makeText(_activity, _activity.getString(R.string.you_need_to_enter_the_device_id), Toast.LENGTH_SHORT).show();
}
});
_dialog.setButton(DialogInterface.BUTTON_NEGATIVE, _activity.getString(R.string.close), (dialog, which) -> _dialog.dismiss());
_dialog.show();
}
public static void changeCDROM(String _path, Activity _activity) {
if (isUsingQ35(lastQemuCommand)) {
if (isQMPCommandSuccess(QmpClient.sendCommand(changeRemovableDevicesQMPCommand("ide2-cd0", _path)))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.changed), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.change_failed), Toast.LENGTH_SHORT).show();
}
} else {
if (isQMPCommandSuccess(QmpClient.sendCommand(changeRemovableDevicesQMPCommand("ide1-cd0", _path)))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.changed), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.change_failed), Toast.LENGTH_SHORT).show();
}
}
}
public static void changeFloppyDriveA(String _path, Activity _activity) {
if (isQMPCommandSuccess(QmpClient.sendCommand(changeRemovableDevicesQMPCommand("floppy0", _path)))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.changed), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.change_failed), Toast.LENGTH_SHORT).show();
}
}
public static void changeFloppyDriveB(String _path, Activity _activity) {
if (isQMPCommandSuccess(QmpClient.sendCommand(changeRemovableDevicesQMPCommand("floppy1", _path)))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.changed), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.change_failed), Toast.LENGTH_SHORT).show();
}
}
public static void changeSDCard(String _path, Activity _activity) {
if (isQMPCommandSuccess(QmpClient.sendCommand(changeRemovableDevicesQMPCommand("sd0", _path)))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.changed), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.change_failed), Toast.LENGTH_SHORT).show();
}
}
public static void ejectCDROM(Activity _activity) {
if (isUsingQ35(lastQemuCommand)) {
if (isQMPCommandSuccess(QmpClient.sendCommand(ejectRemovableDevicesQMPCommand("ide2-cd0")))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.ejected), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.eject_failed), Toast.LENGTH_SHORT).show();
}
} else {
if (isQMPCommandSuccess(QmpClient.sendCommand(ejectRemovableDevicesQMPCommand("ide1-cd0")))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.ejected), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.eject_failed), Toast.LENGTH_SHORT).show();
}
}
}
public static void ejectFloppyDriveA(Activity _activity) {
if (isQMPCommandSuccess(QmpClient.sendCommand(ejectRemovableDevicesQMPCommand("floppy0")))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.ejected), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.eject_failed), Toast.LENGTH_SHORT).show();
}
}
public static void ejectFloppyDriveB(Activity _activity) {
if (isQMPCommandSuccess(QmpClient.sendCommand(ejectRemovableDevicesQMPCommand("floppy1")))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.ejected), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.eject_failed), Toast.LENGTH_SHORT).show();
}
}
public static void ejectSDCard(Activity _activity) {
if (isQMPCommandSuccess(QmpClient.sendCommand(ejectRemovableDevicesQMPCommand("sd0")))) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.ejected), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.eject_failed), Toast.LENGTH_SHORT).show();
}
}
public static void changeRemovableDevice(String _deviceID, String _filepath, Activity _activity) {
String _result = QmpClient.sendCommand(changeRemovableDevicesQMPCommand(_deviceID, _filepath));
if (isQMPCommandSuccess(_result)) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.changed), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing()) {
if (_result.contains("is not removable")) {
Toast.makeText(_activity, _activity.getString(R.string.this_is_not_a_removable_device), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(_activity, _activity.getString(R.string.change_failed), Toast.LENGTH_SHORT).show();
}
}
}
}
public static void ejectRemovableDevice(String _deviceID, Activity _activity) {
String _result = QmpClient.sendCommand(ejectRemovableDevicesQMPCommand(_deviceID));
if (isQMPCommandSuccess(_result)) {
if (_activity != null && !_activity.isFinishing())
Toast.makeText(_activity, _activity.getString(R.string.ejected), Toast.LENGTH_SHORT).show();
} else {
if (_activity != null && !_activity.isFinishing()) {
if (_result.contains("is not removable")) {
Toast.makeText(_activity, _activity.getString(R.string.this_is_not_a_removable_device), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(_activity, _activity.getString(R.string.eject_failed), Toast.LENGTH_SHORT).show();
}
}
}
}
public static void setVNCPasswordWithDelay(String _password) {
new Thread(() -> {
try {
Thread.sleep(1000);
setVNCPassword(_password);
} catch (InterruptedException e) {
Log.d(TAG, "setVNCPasswordWithDelay: " + e.getMessage());
}
}).start();
}
public static void setVNCPassword(String _password) {
String _result = QmpClient.sendCommand(changeVNCPasswordQMPCommand(_password));
if (isQMPCommandSuccess(_result)) {
Log.d(TAG, "setVNCPassword: Success");
} else {
Log.d(TAG, "setVNCPassword: Failed");
}
}
@NonNull
@Contract(pure = true)
public static String changeRemovableDevicesQMPCommand(String _device, String _filepath) {
return "{ \n" +
" \"execute\": \"blockdev-change-medium\", \n" +
" \"arguments\": { \n" +
" \"device\": \"" + _device + "\", \n" +
" \"filename\": \"" + _filepath + "\", \n" +
" \"format\": \"raw\" \n" +
" } \n" +
"}";
}
@NonNull
@Contract(pure = true)
public static String ejectRemovableDevicesQMPCommand(String _device) {
return "{ \"execute\": \"eject\", \"arguments\": { \"device\": \""+ _device +"\" } }";
}
public static String getAllDevicesInQemu() {
return QmpClient.sendCommand("{ \"execute\": \"query-block\" }");
}
public static String changeVNCPasswordQMPCommand(String _password) {
return "{ \"execute\": \"change-vnc-password\", \"arguments\": { \"password\": \"" + _password +"\" } }";
}
public static boolean isQMPCommandSuccess(String _result) {
if (_result == null) return false;
Log.d("VMManager", "isQMPCommandSuccess: " + _result);
return _result.contains("\"return\": {}");
}
@Contract(pure = true)
public static boolean isUsingQemuARM(@NonNull String _qemuCommand) {
return _qemuCommand.contains("qemu-system-a");
}
@Contract(pure = true)
public static boolean isUsingQemuPowerPC(@NonNull String _qemuCommand) {
return _qemuCommand.contains("qemu-system-p");
}
public static boolean isUsingQ35(@NonNull String _qemuCommand) {
return _qemuCommand.contains("-M q35")
|| _qemuCommand.contains("-machine q35")
|| _qemuCommand.contains("-M pc-q35")
|| _qemuCommand.contains("-machine pc-q35");
}
}