diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index d489a5c..9e11c31 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -1,82 +1,43 @@ -name: Android Release Build +name: Android CI on: - workflow_dispatch: - inputs: - release_tag: - description: 'Release tag for the new version' - required: true - default: 'v2.9.3' - release_notes: - description: 'Release notes for the new version' - required: true - default: 'Initial release' + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] jobs: build: + runs-on: ubuntu-latest + steps: - - name: Check out the repository - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: '17' + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: gradle - - name: Chmod gradlew - run: chmod +x ./gradlew + - name: Grant execute permission for gradlew + run: chmod +x gradlew - - name: Build Android app in release mode - run: ./gradlew assembleRelease + - name: Build Debug APK + run: ./gradlew assembleDebug - - name: Upload APK - uses: actions/upload-artifact@v3 - with: - name: app-release.apk - path: app/build/outputs/apk/release/app-release.apk + - name: Build Release APK + run: ./gradlew assembleRelease - - name: Download vectras-vm-arm64-v8a.tar.gz - run: wget -O vectras-vm-arm64-v8a.tar.gz https://github.com/xoureldeen/Vectras-VM-Android/releases/download/v2.9.2/vectras-vm-arm64-v8a.tar.gz + - name: Upload Debug APK as artifact + uses: actions/upload-artifact@v3 + with: + name: android-debug-apk + path: app/build/outputs/apk/debug/app-debug.apk - - name: Download vectras-vm-x86_64.tar.gz - run: wget -O vectras-vm-x86_64.tar.gz https://github.com/xoureldeen/Vectras-VM-Android/releases/download/v2.9.2/vectras-vm-x86_64.tar.gz - - release: - needs: build - runs-on: ubuntu-latest - steps: - - name: Create a release - id: create_release - uses: actions/create-release@v1 - with: - tag_name: ${{ github.event.inputs.release_tag }} - release_name: Release ${{ github.event.inputs.release_tag }} - body: ${{ github.event.inputs.release_notes }} - draft: false - prerelease: false - - - name: Upload APK to release - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: app/build/outputs/apk/release/app-release.apk - asset_name: app-release.apk - asset_content_type: application/vnd.android.package-archive - - - name: Upload vectras-vm-arm64-v8a.tar.gz to release - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: vectras-vm-arm64-v8a.tar.gz - asset_name: vectras-vm-arm64-v8a.tar.gz - asset_content_type: application/gzip - - - name: Upload vectras-vm-x86_64.tar.gz to release - uses: actions/upload-release-asset@v1 - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: vectras-vm-x86_64.tar.gz - asset_name: vectras-vm-x86_64.tar.gz - asset_content_type: application/gzip + - name: Upload Release APK as artifact + uses: actions/upload-artifact@v3 + with: + name: android-release-apk + path: app/build/outputs/apk/release/app-release.apk diff --git a/README.md b/README.md index 8b28e7c..d0aff84 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,11 @@ Welcome to Vectras VM! A virtual machine app for Android based on QEMU that let you emulate various OS including: Windows, MacOS, Linux and Android. -If you want help you can go through [our documention](https://vectrasvm.blackstorm.cc/how.html). If you are short in time, you could get a straight to the point answer in [Vectras Telegram group](http://t.me/vectras_vm_discussion) +If you want help you can go through [our documention](https://vectras.vercel.app/how.html). If you are short in time, you could get a straight to the point answer in [Vectras Telegram group](http://t.me/vectras_vm_discussion) # Installation -> [!NOTE] -> Starting from 2.8, there will be no official support for ARMv7 devices. -You can either download Vectras VM from [releases](https://github.com/epicstudios856/Vectras-VM-Android/releases) or [official website](https://vectras.vercel.app/download.html). +You can either download Vectras VM from [releases](https://github.com/xoureldeen/Vectras-VM-Android/releases) or [official website](https://vectras.vercel.app/download.html). [![OpenAPK](https://www.openapk.net/images/openapk-badge.png)](https://www.openapk.net/vectras-vm/com.vectras.vm/) @@ -50,7 +48,7 @@ Help support the project by funding it. [ico-ko-fi]: https://img.shields.io/badge/Ko--fi-FF5E5B?logo=ko-fi&logoColor=white [link-telegram]: https://t.me/vectras_os -[link-repo]: https://github.com/epicstudios856/Vectras-VM-Android/ -[link-releases]: https://github.com/epicstudios856/Vectras-VM-Android/releases/ +[link-repo]: https://github.com/xoureldeen/Vectras-VM-Android/ +[link-releases]: https://github.com/xoureldeen/Vectras-VM-Android/releases/ [link-buymeacoffee]: https://www.buymeacoffee.com/vectrasvm [link-ko-fi]: https://ko-fi.com/vectrasvm diff --git a/app/build.gradle b/app/build.gradle index 7583095..150e85a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,7 +12,7 @@ android { minSdk minApi targetSdk targetApi versionCode 19 - versionName "v2.9.3" + versionName "v2.9.3-velvet" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true } diff --git a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java index 5d61573..32485a8 100644 --- a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java +++ b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java @@ -256,11 +256,11 @@ public class MainSettingsManager extends AppCompatActivity mHandler = new Handler(); - Preference prefIfType = findPreference("ifType"); - if (getArch(activity).equals("ARM64")) - if (prefIfType != null) { - prefIfType.setVisible(false); - } + //Preference prefIfType = findPreference("ifType"); + //if (getArch(activity).equals("ARM64")) + //if (prefIfType != null) { + //prefIfType.setVisible(false); + //} Preference pref = findPreference("vmArch"); if (pref != null) { @@ -577,7 +577,7 @@ public class MainSettingsManager extends AppCompatActivity public static String getIfType(Activity activity) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); - return prefs.getString("ifType", "ide"); + return prefs.getString("ifType", ""); } public static void setBoot(Activity activity, String boot) { diff --git a/app/src/main/java/com/vectras/vm/AboutActivity.java b/app/src/main/java/com/vectras/vm/AboutActivity.java index 753821d..963a889 100644 --- a/app/src/main/java/com/vectras/vm/AboutActivity.java +++ b/app/src/main/java/com/vectras/vm/AboutActivity.java @@ -8,10 +8,10 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.LinearLayoutManager; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; import com.google.android.gms.ads.LoadAdError; @@ -20,7 +20,7 @@ import com.google.android.gms.ads.initialization.InitializationStatus; import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; import com.google.android.gms.ads.interstitial.InterstitialAd; import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback; -import com.vectras.vm.adapters.GithubUserAdapter; +import com.vectras.vm.adapters.GithubUserAdapter; import com.vectras.vm.utils.UIUtils; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; @@ -165,9 +165,9 @@ public class AboutActivity extends AppCompatActivity implements View.OnClickList Log.d("TAG", "The interstitial ad wasn't ready yet."); } - TextView textversionname = findViewById(R.id.versionname); - PackageInfo pinfo = MainActivity.activity.getAppInfo(getApplicationContext()); - textversionname.setText(pinfo.versionName); + //TextView textversionname = findViewById(R.id.versionname); + //PackageInfo pinfo = MainActivity.activity.getAppInfo(getApplicationContext()); + //textversionname.setText(pinfo.versionName); RecyclerView recyclerView = findViewById(R.id.github_users_recycler_view); String[] usernames = {"vectras-team", "xoureldeen", "ahmedbarakat2007", "anbui2004"}; diff --git a/app/src/main/java/com/vectras/vm/CustomRomActivity.java b/app/src/main/java/com/vectras/vm/CustomRomActivity.java index a9a1e4b..1751b98 100644 --- a/app/src/main/java/com/vectras/vm/CustomRomActivity.java +++ b/app/src/main/java/com/vectras/vm/CustomRomActivity.java @@ -295,7 +295,7 @@ public class CustomRomActivity extends AppCompatActivity { } cdrom.setText(""); - Pattern pattern = Pattern.compile("-drive index=1,media=cdrom,file='([^']*)'"); + Pattern pattern = Pattern.compile(cdromPatternCompile()); Matcher matcher = pattern.matcher(qemu.getText().toString()); if (matcher.find()) { @@ -441,7 +441,7 @@ public class CustomRomActivity extends AppCompatActivity { icon.setText(current.itemIcon); drive.setText(current.itemPath); - Pattern pattern = Pattern.compile("-drive index=1,media=cdrom,file='([^']*)'"); + Pattern pattern = Pattern.compile(cdromPatternCompile()); Matcher matcher = pattern.matcher(current.itemExtra); if (matcher.find()) { @@ -591,57 +591,7 @@ public class CustomRomActivity extends AppCompatActivity { } }).start(); } else if (requestCode == 1002 && resultCode == RESULT_OK) { - Uri content_describer = ReturnedIntent.getData(); - File selectedFilePath = new File(getPath(content_describer)); - drive.setText(AppConfig.maindirpath + "roms/" + title.getText().toString() + "/" + selectedFilePath.getName()); - loadingPb.setVisibility(View.VISIBLE); - custom.setVisibility(View.GONE); - new Thread(new Runnable() { - @Override - public void run() { - FileInputStream File = null; - try { - File = (FileInputStream) getContentResolver().openInputStream(content_describer); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - try { - try { - OutputStream out = new FileOutputStream(new File(AppConfig.maindirpath + "roms/" + title.getText().toString() + "/" + selectedFilePath.getName())); - try { - // Transfer bytes from in to out - byte[] buf = new byte[1024]; - int len; - while ((len = File.read(buf)) > 0) { - out.write(buf, 0, len); - } - } finally { - out.close(); - } - } finally { - Runnable runnable = new Runnable() { - @Override - public void run() { - loadingPb.setVisibility(View.GONE); - custom.setVisibility(View.VISIBLE); - } - }; - activity.runOnUiThread(runnable); - File.close(); - } - } catch (IOException e) { - Runnable runnable = new Runnable() { - @Override - public void run() { - loadingPb.setVisibility(View.GONE); - custom.setVisibility(View.VISIBLE); - UIUtils.UIAlert(activity, "error", e.toString()); - } - }; - activity.runOnUiThread(runnable); - } - } - }).start(); + selectedDiskFile(ReturnedIntent.getData()); } else if (requestCode == 1003 && resultCode == RESULT_OK) { Uri content_describer = ReturnedIntent.getData(); File selectedFilePath = new File(getPath(content_describer)); @@ -652,10 +602,21 @@ public class CustomRomActivity extends AppCompatActivity { String qemuText = qemu.getText().toString(); String cdromParam = "-drive index=1,media=cdrom,file='" + cdromPath + "'"; - Pattern pattern = Pattern.compile("-drive index=1,media=cdrom,file='(.*?)'"); + if (MainSettingsManager.getArch(activity).equals("ARM64")) { + if (!qemu.getText().toString().contains("-device nec-usb-xhci")) { + qemu.setText(qemu.getText().toString() + " -device nec-usb-xhci"); + } + cdromParam = "-device usb-storage,drive=cdrom -drive if=none,id=cdrom,format=raw,media=cdrom,file='" + cdromPath + "'"; + } else { + if (MainSettingsManager.getIfType(activity).isEmpty()) { + cdromParam = "-cdrom '" + cdromPath + "'"; + } + } + + Pattern pattern = Pattern.compile(cdromPatternCompile2()); Matcher matcher = pattern.matcher(qemuText); - if (!qemuText.contains("-drive index=1,media=cdrom,file=")) { + if (!qemuText.contains("-drive index=1,media=cdrom,file=") || !qemuText.contains("-cdrom") || !qemuText.contains("-device usb-storage,drive=cdrom -drive if=none,id=cdrom,format=raw,media=cdrom,file=")) { qemu.append(" " + cdromParam); } else { if (matcher.find()) { @@ -792,7 +753,7 @@ public class CustomRomActivity extends AppCompatActivity { errorjsondialog(); File isoFile = new File(cdrom.getText().toString()); - if (isoFile.exists() && !qemu.getText().toString().contains("-drive index=1,media=cdrom,file=")) { + if (isoFile.exists() && !qemu.getText().toString().contains(cdrom.getText().toString())) { isoFile.delete(); } @@ -1064,14 +1025,16 @@ public class CustomRomActivity extends AppCompatActivity { title.setText(jObj.getString("title")); icon.setText(AppConfig.maindirpath + "roms/" + _filename.replace(".cvbi", "") + "/" + jObj.getString("icon")); - drive.setText(AppConfig.maindirpath - + "roms/" + _filename.replace(".cvbi", "") + "/" + jObj.getString("drive")); + if (!jObj.getString("drive").isEmpty()) { + drive.setText(AppConfig.maindirpath + + "roms/" + _filename.replace(".cvbi", "") + "/" + jObj.getString("drive")); + } qemu.setText(jObj.getString("qemu")); ImageView ivIcon = findViewById(R.id.ivIcon); Bitmap bmImg = BitmapFactory.decodeFile(AppConfig.maindirpath + "roms/" + _filename.replace(".cvbi", "") + "/" + jObj.getString("icon")); ivIcon.setImageBitmap(bmImg); - UIUtils.UIAlert(activity, getResources().getString(R.string.from) + ": " + jObj.getString("author") + "\n\n" + Html.fromHtml(jObj.getString("desc")), getResources().getString(R.string.description) + ":"); + UIUtils.UIAlert(activity, getResources().getString(R.string.from) + ": " + jObj.getString("author"), getResources().getString(R.string.description) + ":\n\n" + Html.fromHtml(jObj.getString("desc"))); } catch (JSONException e) { throw new RuntimeException(e); } @@ -1100,6 +1063,104 @@ public class CustomRomActivity extends AppCompatActivity { } } + private void selectedDiskFile(Uri _content_describer) { + File selectedFilePath = new File(getPath(_content_describer)); + if (VectrasApp.isADiskFile(selectedFilePath.getPath())) { + startProcessingHardDriveFile(_content_describer); + } else { + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle(getResources().getString(R.string.problem_has_been_detected)); + alertDialog.setMessage(getResources().getString(R.string.file_format_is_not_supported)); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, getResources().getString(R.string.continuetext), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + startProcessingHardDriveFile(_content_describer); + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + alertDialog.dismiss(); + } + }); + alertDialog.show(); + } + } + + private void startProcessingHardDriveFile (Uri _content_describer) { + LinearLayout custom = findViewById(R.id.custom); + File selectedFilePath = new File(getPath(_content_describer)); + drive.setText(AppConfig.maindirpath + "roms/" + title.getText().toString() + "/" + selectedFilePath.getName()); + loadingPb.setVisibility(View.VISIBLE); + custom.setVisibility(View.GONE); + new Thread(new Runnable() { + @Override + public void run() { + FileInputStream File = null; + try { + File = (FileInputStream) getContentResolver().openInputStream(_content_describer); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + try { + try { + OutputStream out = new FileOutputStream(new File(AppConfig.maindirpath + "roms/" + title.getText().toString() + "/" + selectedFilePath.getName())); + try { + // Transfer bytes from in to out + byte[] buf = new byte[1024]; + int len; + while ((len = File.read(buf)) > 0) { + out.write(buf, 0, len); + } + } finally { + out.close(); + } + } finally { + Runnable runnable = new Runnable() { + @Override + public void run() { + loadingPb.setVisibility(View.GONE); + custom.setVisibility(View.VISIBLE); + } + }; + activity.runOnUiThread(runnable); + File.close(); + } + } catch (IOException e) { + Runnable runnable = new Runnable() { + @Override + public void run() { + loadingPb.setVisibility(View.GONE); + custom.setVisibility(View.VISIBLE); + UIUtils.UIAlert(activity, "error", e.toString()); + } + }; + activity.runOnUiThread(runnable); + } + } + }).start(); + } + + private String cdromPatternCompile() { + //Matches any string of characters that does not contain single quotes + if (MainSettingsManager.getArch(activity).equals("ARM64")) { + return "-device usb-storage,drive=cdrom -drive if=none,id=cdrom,format=raw,media=cdrom,file='([^']*)'"; + } else if (MainSettingsManager.getIfType(activity).isEmpty()) { + return "-cdrom '([^']*)'"; + } else { + return "-drive index=1,media=cdrom,file='([^']*)'"; + } + } + + private String cdromPatternCompile2() { + //Matches any string of characters, but will try to match the shortest string possible + if (MainSettingsManager.getArch(activity).equals("ARM64")) { + return "-device usb-storage,drive=cdrom -drive if=none,id=cdrom,format=raw,media=cdrom,file='(.*?)'"; + } else if (MainSettingsManager.getIfType(activity).isEmpty()) { + return "-cdrom '(.*?)'"; + } else { + return "-drive index=1,media=cdrom,file='(.*?)'"; + } + } + public void onDestroy() { super.onDestroy(); File lol = new File(AppConfig.maindirpath + drive.getText().toString()); diff --git a/app/src/main/java/com/vectras/vm/MainActivity.java b/app/src/main/java/com/vectras/vm/MainActivity.java index 80cd062..af82e20 100644 --- a/app/src/main/java/com/vectras/vm/MainActivity.java +++ b/app/src/main/java/com/vectras/vm/MainActivity.java @@ -131,6 +131,7 @@ public class MainActivity extends AppCompatActivity { private AlertDialog alertDialog; private boolean doneonstart = false; public static boolean isActivate = false; + public boolean skipIDEwithARM64DialogInStartVM = false; @Override protected void onCreate(Bundle bundle) { @@ -756,7 +757,7 @@ public class MainActivity extends AppCompatActivity { int versionCode = pinfo.versionCode; String versionName = pinfo.versionName; - if (versionCode < obj.getInt("versionCode") || !versionName.equals(obj.getString("versionName"))) { + if (versionCode < obj.getInt("versionCode") || !obj.getString("versionName").contains(versionName)) { AlertDialog.Builder alert = new AlertDialog.Builder(activity, R.style.MainDialogTheme); alert.setTitle("Install the latest version") .setMessage(Html.fromHtml(obj.getString("Message") + "

update size:
" + obj.getString("size"))) @@ -951,6 +952,27 @@ public class MainActivity extends AppCompatActivity { } } + if (MainSettingsManager.getArch(activity).equals("ARM64") && MainSettingsManager.getIfType(activity).equals("ide") && !activity.skipIDEwithARM64DialogInStartVM) { + AlertDialog abiAlertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + abiAlertDialog.setTitle(activity.getResources().getString(R.string.problem_has_been_detected)); + abiAlertDialog.setMessage(activity.getResources().getString(R.string.you_cannot_use_IDE_hard_drive_type_with_ARM64)); + abiAlertDialog.setButton(DialogInterface.BUTTON_POSITIVE, activity.getResources().getString(R.string.continuetext), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + activity.skipIDEwithARM64DialogInStartVM = true; + startVM(vmName, env, itemExtra, itemPath); + } + }); + abiAlertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, activity.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + + } + }); + abiAlertDialog.show(); + return; + } else if (activity.skipIDEwithARM64DialogInStartVM) { + activity.skipIDEwithARM64DialogInStartVM = false; + } + boolean isRunning = isMyServiceRunning(MainService.class); ProgressDialog progressDialog = new ProgressDialog(activity, R.style.MainDialogTheme); @@ -1382,6 +1404,10 @@ public class MainActivity extends AppCompatActivity { } } + public static void mdatasize2() { + linearnothinghere.setVisibility(View.VISIBLE); + } + private void checkpermissions() { if (VectrasApp.checkpermissionsgranted(activity, true)) { errorjsondialog(); diff --git a/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java b/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java index 69cf7bb..3c2dd52 100644 --- a/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java +++ b/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java @@ -311,7 +311,7 @@ public class AdapterMainRoms extends RecyclerView.Adapter= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + MainSettingsManager.setVmUi(this, "VNC"); + } + } finish(); } } diff --git a/app/src/main/java/com/vectras/vm/StartVM.java b/app/src/main/java/com/vectras/vm/StartVM.java index 23ed3a7..f5dc847 100644 --- a/app/src/main/java/com/vectras/vm/StartVM.java +++ b/app/src/main/java/com/vectras/vm/StartVM.java @@ -37,48 +37,87 @@ public class StartVM { params.add("qemu-system-ppc"); String ifType; - if (MainSettingsManager.getArch(activity).equals("ARM64")) - ifType = "ahci"; - else - ifType= MainSettingsManager.getIfType(activity); + ifType= MainSettingsManager.getIfType(activity); String cdrom; + String hdd0; String hdd1; - if (!(img.length() == 0)) { - String hdd0 = "-drive"; - hdd0 += " index=0"; - hdd0 += ",media=disk"; - hdd0 += ",if=" + ifType; - hdd0 += ",file='" + img + "'"; + if (!img.isEmpty()) { + if (ifType.isEmpty()) { + hdd0 = "-hda"; + hdd0 += " '" + img + "'"; + } else { + hdd0 = "-drive"; + hdd0 += " index=0"; + hdd0 += ",media=disk"; + hdd0 += ",if=" + ifType; + hdd0 += ",file='" + img + "'"; + + if ((MainSettingsManager.getArch(activity).equals("ARM64") && ifType.equals("ide")) || MainSettingsManager.getArch(activity).equals("PPC")) { + hdd0 = "-drive"; + hdd0 += " index=0"; + hdd0 += ",media=disk"; + hdd0 += ",file='" + img + "'"; + } + } params.add(hdd0); } File cdromFile = new File(filesDir + "/data/Vectras/drive.iso"); if (cdromFile.exists()) { - cdrom = "-drive"; - cdrom += " index=1"; - cdrom += ",media=cdrom"; - cdrom += ",file='" + cdromFile.getPath() + "'"; + if (MainSettingsManager.getArch(activity).equals("ARM64")) { + cdrom = "-device"; + cdrom += " usb-storage,drive=cdrom"; + cdrom += " -drive"; + cdrom += " if=none,id=cdrom,format=raw,media=cdrom,file='" + cdromFile.getPath() + "'"; + if (!extras.contains("-device nec-usb-xhci")) { + cdrom += " -device"; + cdrom += " qemu-xhci"; + cdrom += " -device"; + cdrom += " nec-usb-xhci"; + } + } else { + if (ifType.isEmpty()) { + cdrom = "-cdrom"; + cdrom += " '" + cdromFile.getPath() + "'"; + } else { + cdrom = "-drive"; + cdrom += " index=1"; + cdrom += ",media=cdrom"; + cdrom += ",file='" + cdromFile.getPath() + "'"; + } + } + params.add(cdrom); } File hdd1File = new File(filesDir + "/data/Vectras/hdd1.qcow2"); if (hdd1File.exists()) { - hdd1 = "-drive"; - hdd1 += " index=2"; - hdd1 += ",media=disk"; - hdd1 += ",if=" + ifType; - hdd1 += ",file='" + hdd1File.getPath() + "'"; + if (ifType.isEmpty()) { + hdd1 = "-hdb"; + hdd1 += " '" + hdd1File.getPath() + "'"; + } else { + hdd1 = "-drive"; + hdd1 += " index=2"; + hdd1 += ",media=disk"; + hdd1 += ",if=" + ifType; + hdd1 += ",file='" + hdd1File.getPath() + "'"; + } + params.add(hdd1); } if (MainSettingsManager.getSharedFolder(activity)) { String driveParams = "-drive "; - driveParams += "index=3,media=disk,file=fat:"; + if (ifType.isEmpty()) { + driveParams += "media=disk,file=fat:"; + } else { + driveParams += "index=3,media=disk,file=fat:"; + } driveParams += "rw:"; //Disk Drives are always Read/Write driveParams += FileUtils.getExternalFilesDirectory(activity).getPath() + "/SharedFolder,format=raw"; params.add(driveParams); @@ -88,7 +127,12 @@ public class StartVM { memoryStr += RamInfo.vectrasMemory(); String boot = "-boot "; - boot += MainSettingsManager.getBoot(activity); + if (extras.contains(".iso ")) { + + boot += MainSettingsManager.getBoot(activity); + } else { + boot += "c"; + } String soundDevice = "-audiodev pa,id=pa -device AC97,audiodev=pa"; @@ -145,14 +189,8 @@ public class StartVM { params.add(qmpParams); } - if (!MainSettingsManager.getArch(activity).equals("PPC")) { - if (!MainSettingsManager.getArch(activity).equals("ARM64")) { - params.add("-monitor"); - } - } - if (MainSettingsManager.getArch(activity).equals("ARM64")) { - //params.add("stdio"); - } else if (!MainSettingsManager.getArch(activity).equals("PPC")) { + if (!MainSettingsManager.getArch(activity).equals("PPC") || !MainSettingsManager.getArch(activity).equals("ARM64")) { + params.add("-monitor"); params.add("vc"); } } else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) { @@ -169,7 +207,23 @@ public class StartVM { params.add("-qmp"); params.add("tcp:localhost:4444,server,nowait"); - params.add(extras); + String finalextra; + + if (ifType.isEmpty()) { + if (extras.contains("-drive index=1,media=cdrom,file=")) { + finalextra = extras.replace("-drive index=1,media=cdrom,file=", "-cdrom "); + } else { + finalextra = extras; + } + } else { + if (extras.contains("-cdrom ")) { + finalextra = extras.replace("-cdrom ", "-drive index=1,media=cdrom,file="); + } else { + finalextra = extras; + } + } + + params.add(finalextra); return String.join(" ", params); } diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml index f0c3d7e..46356ca 100644 --- a/app/src/main/res/layout/activity_splash.xml +++ b/app/src/main/res/layout/activity_splash.xml @@ -19,7 +19,7 @@ android:id="@+id/versionname" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="" + android:text="@string/app_version" android:padding="8dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" diff --git a/app/src/main/res/layout/content_about.xml b/app/src/main/res/layout/content_about.xml index 236db19..bd4ff8a 100644 --- a/app/src/main/res/layout/content_about.xml +++ b/app/src/main/res/layout/content_about.xml @@ -64,7 +64,7 @@ android:id="@+id/versionname" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="" + android:text="@string/app_version" android:textSize="12sp" /> @@ -114,7 +114,7 @@ android:layout_height="wrap_content" android:gravity="center" android:textSize="18sp" - android:textStyle="bold" + android:textStyle="bold" android:padding="8dp" android:text="Developers" /> diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 3b81027..e80cc70 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -3,7 +3,7 @@ Vectras VM - v2.9.3 + v2.9.3 (Velvet) مستقر الرئيسية سجل الأحداث @@ -227,7 +227,7 @@ سيتم عرض الرومات المستوردة هنا الإصدار: QEMU - العمارة: + المعمارية: قيد التشغيل متوقف الخدمة: @@ -268,7 +268,7 @@ التحقق من تحديثات البرنامج وضع الليل وصف - QEMU WEBSITE + موقع QEMU POWERPC QEMU ARM64 QEMU x86_64 QEMU (موصى به) @@ -283,10 +283,10 @@ "تمت الإزالة بنجاح!" فريق Vectras VM ونجوين باو آن بوي المستودع - قناة تلغرام - يوتيوب - إنستغرام - فيسبوك + قناة Telegram + YouTube + Instagram + Facebook سجل التغييرات اللغة تعيين @@ -295,19 +295,19 @@ وحدة المعالجة المركزية حفظ التغييرات أمر إنشاء QEMU - احصل عليه + الحصول عليه تأكد من أنك قد اخترت روم أو CDROM لتمهيد نظام التشغيل منه. قد لا تحتاج إلى اختياره إذا كنت قد أضفته إلى معلمات QEMU. إيقاف QEMU جارٍ التثبيت... عرض VNC - إعداد الصوت لـ Termux + إعداد الصوت لـTermux هذا يمكّن الآلات الافتراضية التي تعمل على Vectras VM من تشغيل الصوت باستخدام Termux. إذا لم تقم بإعداد Termux بعد، حدد بدء الإعداد، سيتم نسخ الأمر تلقائيًا إلى الحافظة، تحتاج إلى لصق هذا الأمر وتشغيله في Termux لإكمال الإعداد. في المرات القادمة، تأكد من تشغيل Termux لتشغيل الصوت. تم النسخ. بدء الإعداد Termux غير مثبت تحتاج إلى تثبيت Termux قبل الإعداد. في انتظارك... - نوصي باستخدام أمر الإنشاء لجعل إنشاء آلة افتراضية أسهل وأبسط. + نوصي باستخدام تطبيق Create Command لجعل إنشاء آلة افتراضية أسهل وأبسط. عذرًا! وحدة المعالجة المركزية على جهازك لا تحتوي على التعليمات اللازمة لتعمل Vectras VM. تحذير! @@ -338,10 +338,10 @@ مثبت إيقاف جميع العمليات هل تريد إيقاف جميع عمليات QEMU؟ - سيتم إيقاف تشغيل جميع الآلات الافتراضية قسراً. + سيتم فرض إيقاف تشغيل جميع الآلات الافتراضية بالقوة. الإجمالي: المستخدم: - المجاني: + الحر: مستخدم لا يوجد شيء هنا لأنه لا توجد آلة افتراضية قيد التشغيل. لحظة من فضلك... @@ -362,6 +362,8 @@ سيتم حذف أقراص ROM والملفات والمجلدات التي لم تعد قيد الاستخدام. انتقل إلى متجر ROM هل تريد أن تتعلم المزيد عن QEMU؟ + قد لا تعمل الأشياء لأن تنسيق الملف غير مدعوم. هل تريد المتابعة؟ + لا يمكنك استخدام نوع محرك الأقراص الثابتة IDE مع ARM64. إذا تابعت، فسيتم استخدام نوع محرك الأقراص الثابتة الافتراضي. Vterm diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml new file mode 100644 index 0000000..a48e1cb --- /dev/null +++ b/app/src/main/res/values-zh/strings.xml @@ -0,0 +1,354 @@ + + + Vectras VM + 主页 + 日志 + 启动虚拟机 + 虚拟机已启动! + 虚拟机已关闭! + NO PROCCESSES! + UNKNOWN STATE! + "To use External Mouse: \tDisable Mouse Acceleration inside the Guest OS. \t\tFor DSL use command: xset m 1 \t\tFor Other OSes disable \"Enhance pointer Precision\" or choose Mouse \"usb-tablet\" from Vectras main options. \tPlug in or Pair your USB/Bluetooth Mouse and press OK \tMove your mouse pointer to all desktop sides to calibrate. " + 地址 + 重置 + 停机 + 设备 + 外部鼠标设备 + 自适应屏幕 + 全屏 + "切换全屏 " + 放大 + 缩小 + 鼠标右键 + 帮助 + 驱动 + 音频 + 隐藏工具栏 + 查看日志 + 模式 + 键盘 + 名称 + 大小: + 可用性: + 隐藏 + 登录活动 + 邮箱 + 密码 + 登录 + 登出 + 使用 google 登录 + 欢迎! + 无效用户名 + 密码必须大于5个字符 + 登录失败 + 简介 + Vectras 官网 + 关于 + 虚拟机详情 + 全名 + 设置 + 继续 + 下载 + 用户名 + 保存 + 内存使用量 + Hello blank fragment + 安装 ROM + 重连 + 显示 + 校准鼠标 + 隐藏控制器 + 移除 + 查看日志 + SetArchActivity + First Fragment + Second Fragment + 下一个 + 上一个 + 硬件鼠标模式 + 上一个选项 + 下一个选项 + 选择 qemu 架构: + 选择 qemu 架构: + 导入自定义 ROM \".CVBI\" + ROM 名称 + QEMU 参数 + ROM 图标 + ADD + 导入 ISO + 导入 + 需要权限! + 由于安卓政策,需要通知权限才能发送虚拟机通知! + 鼠标模式 + 导出 + 验证电子邮件已发送。 + 登出 + Guest + 资源管理器 + 忘记密码? + 请我一杯咖啡 + 新建一个虚拟机 + 下箭头 + 左箭头 + 右箭头 + 上箭头 + 自动 + 发送文本 + 发送文本/不保存 + 鼠标 @ + 关闭 + 颜色格式化 + 颜色模式 + 连接 + 连接 + 复制列表 + 删除连接 + 删除已选择的键 + 删除键列表 + 断开连接 + 导出 + 导出至文件 + 输入要发送的文本 + 发送文本 + 适应屏幕 + 强制全屏位图 + 导入/导出设置 + 导入 + 从文件或URL导入 + 详情 + If you need help, please check the <a href=http://code.google.com/p/android-vnc-viewer/wiki/Documentation>manual</a> (press phone\'s Menu button to access manual and other menu items), or the <a href=http://code.google.com/p/android-vnc-viewer/wiki/faq>FAQ</a>.<br> + 欢迎 + <br>--Sent text is remembered across sessions (optionally)<br>--Import/Export settings to file<br>--Button with zoom controls to bring up keyboard<br>--Can force tiling mode (very large screens) + 输入模式 + 无平移;轨迹球鼠标 + 鼠标指针控制模式 + 桌面平移模式 + 触摸平移;轨迹球鼠标 + 触摸鼠标;D-Pad Pan + 触摸鼠标平移和缩放 + 触摸板 + 保持 + 不要再次显示 + Keys + 列表 + 列表名 + 本地鼠标指针 + 发送特殊键 + 鼠标跟随平移 + 新建列表 + 昵称 + 关闭 + 打开 + 手册/Wiki + 平移跟随鼠标 + 鼠标跟随平移 + 端口 + Repeater + Enter the repeater address <b>only if</b> you are using an<br><i>UltraVNC</i>-type repeater + Don\'t use repeater + Repeater Information + No repeater + Use this repeater address + 保存为副本 + 缩放比例 + 可缩放的 + 发送 + 再次发送键 + VNC 连接 + 键盘 + 发送键 + 用户名 + 用于 Windows 身份验证 + 启动自定义 VNC 连接 + 终端 + %1$s 目录绝对路径:\"%2$s\" + 安装 + 选择(.TAR.GZ) + 尚未选择 + 修改 + 输入 + 再次尝试 + 日志 + 选项 + 创建虚拟硬盘 + 大小(GB) + 创建 QCOW2 + 镜像名 + 制作镜像 + 导入的 ROM 将在此处显示 + 版本: + 运行中 + 已停止 + 服务: + 解放巴勒斯坦 + 商店 + 无互联网连接 + 检查您的互联网连接 + 正在下载文件… + 文件长度: + 已下载到路径: + 下载成功! + 应用设置 + 主应用设置 + 用户界面 + 主题和ui + 虚拟机设置 + vnc ui 环境 + CPU 模式 + 自定义内存 + 内存(MB) + 声卡 + TB 大小(KB) + kvm 加速 + CPU 核心 + 硬盘类型 + 启动于 + 共享文件夹 + 自定义参数 + VM UI 环境 + X11 分辨率 + 鼠标 + 启动时检查软件更新 + 检查软件更新 + 夜间模式 + 描述 + QEMU 官网 + x86_64(推荐) + 导出 Rom + 你确定吗? + 描述(支持html) + 压缩 CVBI + 请稍候… + 完成! + 已成功删除! + 仓库 + 语言 + 更改应用区域设置 + 您确定要关闭虚拟机吗?要离开此状态但保持一切运行,请点击并按住关机按钮 + 保存更改 + 确保您已选择从中启动操作系统的 ROM 或 CDROM。如果您已将它们添加到 QEMU 参数中,则可能不需要选择它 + 杀死 QEMU + 正在安装… + VNC 显示 + 为 Termux 设置声音 + 这使得在 Vectras VM上运行的虚拟机能够使用Termux播放音频。如果您尚未设置Termux,请选择“开始设置”,该命令将自动复制到剪贴板,您需要粘贴该命令并在Termux中运行以完成设置。下次,确保Termux正在运行以播放声音。 + 已复制 + 启动安装程序 + 未安装 Termux + 您需要在设置之前安装 Termux + 等待着你… + 我们建议您使用 Create 命令,使创建虚拟机更简单、更容易 + 设备上的 CPU 没有 Vectras VM 工作所需的指令 + 警告! + 您设备上的 Android 操作系统或 CPU 不支持64位,这意味着虚拟机在运行时性能较差且不稳定 + 虚拟机列表数据出错。您想全部删除吗? + 全部删除 + 虚拟机列表数据出错,此时无法创建新的虚拟机。要创建新的虚拟机,您需要删除所有虚拟机列表数据。您想全部删除吗? + 检测到问题 + 您尚未添加任何存储设备以开始使用或安装操作系统。您想继续创建吗? + 继续 + 您需要为此虚拟机命名 + 虚拟机无法运行,因为您手机上的 CPU 或 Android 操作系统不支持64位使用多线程 TCG 。您想继续使用单线程 TCG 运行虚拟机吗? + 此 VM 已在运行 + 所有虚拟机都将被删除,包括您的所有 ROM。您想继续吗? + 删除所有 VM + 新建 + 空空如也哦 + 您想现在创建新的虚拟机吗? + 点击底部的“创建”按钮,开始创建新的虚拟机。或者… + 允许访问存储空间 + 您需要允许访问存储空间才能继续 + 允许 + 此时无法创建 VM + 没有数据 + ROM 商店 + 可用的 + 不可用的 + 已安装 + 终止全部 + 您想终止所有 Qemu 进程吗? + 所有正在运行的虚拟机都将被强制关闭 + 总计: + 使用: + 空闲: + 已用: + 空空如也,因为没有 VM 运行 + 请稍等… + 无法连接到服务器 + 加入我们的社区 + 出现了一个严重的问题!此问题是由设备上的 CPU 或 Android 操作系统引起的。您可以加入我们的社区以了解更多信息 + 保留文件? + 您想保留此 ROM 文件和 CD ROM 文件吗? + 保留 + 全部删除 + 不支持的格式,请选择 cvbi 格式的文件 + 出现一个问题,无法继续,因为找不到 cbvi 文件。错误代码:CR_CVBI1 + 发生错误。提取成功,但 cvbi 文件不包含有关此 ROM 的信息,因此将使用一些默认设置。错误代码:CR_CVBI2 + 来自 + 发生错误,无法继续。提取成功,但 cvbi 文件不包含此 ROM 的信息,也不包含任何 ROM 文件。错误代码:CR_CVBI3 + 一些文件被保留,因为其他虚拟机需要它们 + 清理 + 不再使用的 ROM、文件和文件夹将被删除 + 转到 ROM 商店 + 想了解更多关于 QEMU 的信息吗? + 由于不支持该文件格式,因此可能无法正常工作。您想继续吗? + 您不能将 IDE 硬盘类型与 ARM64 一起使用。如果继续,将使用默认硬盘类型 + Vterm 用户 + 在 Vterm 环境中运行命令 + 在 Vterm 环境中运行任意命令 + 新建会话 + 故障保护 + 键盘 + 重置 + 样式 + 终端显示文本 + 保持屏幕打开 + 自动填充密码 + 安装中… + 无法安装 + Vterm 无法安装引导程序包 + 关于 + 再次尝试 + Vterm 只能安装在主用户帐户上 + 已达到的最大终端数 + 在创建新的之前关闭现有的 + 重置终端 + 选择 URL + 点击 URL 进行复制或长按打开 + 分享终端显示文本 + 在终端中找不到 URL。 + URL 已复制到剪贴板 + 发送文本至: + 终止进程(%d) + 真的要终止此会话吗? + 设置会话名称 + 新命名会话 + 创建 + Vterm:Style 插件尚未安装 + 安装 + 退出 + 获取 wakelock + 释放 wakelock + 将文件保存至 ~/downloads/ + 编辑 + 打开文件夹 + 必须授予存储权限 到 Vectras VM 应用程序… + 授予存储权限 + Android battery optimizations should be disabled for the Vectras VM app so that… Check https://developer.android.com/about/versions/oreo/background for more info and https://developer.android.com/guide/components/foreground-services#background-start-restrictions for more info. Also check https://dontkillmyapp.com for info on vendor specific app killers. Depending on vendor you may need to do things like enable AutoStart, disable DuraSpeed, enable `Display pop-up windows while running in the background` for the app. + 禁用电池优化 + "The display over other apps permission should be granted to Vectras VM app for starting foreground activities from background. Check https://developer.android.com/guide/components/activities/background-starts for more info. " + 授予在其它应用上层显示权限 + 已授予 + 已禁用 + 未连接 + " 帮助 " + " 偏好 " + Here you can set value of extra-keys variable like in Termux app (read this) and more (e.g. META). + 日志级别 + 关闭 + Logcat 日志级别设置为 \"%1$s\" + 确定 + 取消 + 取消 + 返回显示 + \ No newline at end of file diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index e578f45..ed2ace3 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -59,10 +59,12 @@ d + DEFAULT IDE VIRTIO + ide virtio diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38d9742..4391df5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,7 +3,7 @@ Vectras VM - v2.9.3 + v2.9.3 (Velvet) Stable Home Logger @@ -362,6 +362,8 @@ ROMs, files and folders that are no longer in use will be deleted. Go to ROM store Want to learn more about QEMU? + Things may not work because the file format is not supported. Do you want to continue? + You cannot use IDE hard drive type with ARM64. If you continue, the default hard drive type will be used. Vterm diff --git a/app/src/main/res/xml/qemu.xml b/app/src/main/res/xml/qemu.xml index b74b7f0..c29ff5f 100644 --- a/app/src/main/res/xml/qemu.xml +++ b/app/src/main/res/xml/qemu.xml @@ -50,7 +50,7 @@