2.9.0 Update

This commit is contained in:
epicstudios856 2024-05-11 02:11:12 +03:00
parent 6b708ac130
commit c654901a09
145 changed files with 22337 additions and 535 deletions

View file

@ -9,7 +9,7 @@ import android.widget.ImageView.ScaleType;
/**
* @author Michael A. MacDonald
*
*
*/
public class ConnectionBean {
@ -30,7 +30,7 @@ public class ConnectionBean {
setAddress(Config.defaultVNCHost);
setUserName(Config.defaultVNCUsername);
setPassword("555555");
setPort(Config.defaultVNCPort + 5901);
setPort(Config.defaultVNCPort + 5900);
setColorModel(Config.defaultVNCColorMode);
if (Config.enable_qemu_fullScreen)
setScaleMode(Config.defaultFullscreenScaleMode);
@ -40,40 +40,40 @@ public class ConnectionBean {
}
private void setUserName(String string) {
this.userName = string;
}
public void setInputMode(String touchZoomMode) {
this.InputMode = touchZoomMode;
}
void setPort(int i) {
this.port = i;
}
void setColorModel(String nameString) {
this.colorModel = nameString;
}
void setAddress(String string) {
this.address = string;
}
void setPassword(String string) {
this.password = string;
}
public long get_Id() {
return 0;
}
@ -82,7 +82,7 @@ public class ConnectionBean {
}
private String getScaleModeAsString() {
return scaleMode;
}
@ -91,91 +91,91 @@ public class ConnectionBean {
}
private void setScaleModeAsString(String string) {
this.scaleMode = string;
}
public String getAddress() {
return this.address;
}
public void setNickname(String address2) {
this.nickname = address2;
}
public int getPort() {
return port;
}
public String getInputMode() {
return this.InputMode;
}
public String getPassword() {
return this.password;
}
public long getForceFull() {
return this.forceFull;
}
public boolean getUseLocalCursor() {
return this.useLocalCursor;
}
public String getNickname() {
return nickname;
}
public String getColorModel() {
return this.colorModel;
}
public void setForceFull(long l) {
this.forceFull = l;
}
public void setUseLocalCursor(boolean checked) {
this.setUseLocalCursor(checked);
}
public void setFollowMouse(boolean b) {
this.followMouse = b;
}
public boolean getFollowMouse() {
return this.followMouse;
}
public String getUserName() {
return userName;
}
public void setConnectionId(long get_Id) {
this.id = get_Id;
}
public boolean getFollowPan() {
return false;
}
}
}

View file

@ -129,11 +129,11 @@ public class Config {
// VNC Defaults
public static String defaultVNCHost = "localhost";
public static final String defaultVNCUsername = "vectras";
public static final String defaultVNCPasswd = "";
public static final String defaultVNCPasswd = "vectras";
//It seems that for new veersion of qemu it expectes a relative number
//It seems that for new version of qemu it expects a relative number
// so we stop using absolute port numbers
public static final int defaultVNCPort = 0;
public static final int defaultVNCPort = 1;
//Keyboard Layout
public static String defaultKeyboardLayout = "en-us";
@ -141,7 +141,7 @@ public class Config {
public static boolean enableToggleKeyboard = false;
// Debug
public static final boolean debug = true;
public static final boolean debug = false;
public static boolean debugQmp = false;
//remove in production
@ -171,7 +171,6 @@ public class Config {
// App config
public static final String datadirpath = VectrasApp.getApp().getExternalFilesDir("data")+"/";
public static final String sharedFolder = datadirpath + "Vectras/ProgramFiles/";
public static String machinename = "VECTRAS";
public static int paused = 0;

View file

@ -10,6 +10,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@ -20,13 +21,20 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;
import androidx.preference.SwitchPreferenceCompat;
import com.vectras.vm.R;
import com.vectras.vm.SplashActivity;
import com.vectras.vm.VectrasApp;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class MainSettingsManager extends AppCompatActivity
implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
public static MainSettingsManager activity;
@ -224,8 +232,6 @@ public class MainSettingsManager extends AppCompatActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (SDK_INT > 33)
findPreference("sharedFolder").setEnabled(false);
mHandler = new Handler();
Preference pref = findPreference("vmArch");
@ -268,7 +274,14 @@ public class MainSettingsManager extends AppCompatActivity
});
}
Preference pref3 = findPreference("MTTCG");
if (Objects.equals(getArch(activity), "I386")) { // I386 DOES NOT SUPPORT SHARED FOLDER
SwitchPreferenceCompat sharedPref = findPreference("sharedFolder");
sharedPref.setEnabled(false);
sharedPref.setChecked(false);
setSharedFolder(activity, false);
}
SwitchPreferenceCompat pref3 = findPreference("MTTCG");
if (pref3 != null) {
pref3.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@ -294,6 +307,77 @@ public class MainSettingsManager extends AppCompatActivity
}
});
String ABI = Build.SUPPORTED_ABIS[0];
if (ABI.contains("x86") && (Objects.equals(getArch(activity), "X86_64") || Objects.equals(getArch(activity), "I386"))) {
assert pref2 != null;
pref2.setVisible(true);
} else if (Objects.equals(ABI, "arm64-v8a") && Objects.equals(getArch(activity), "ARM64")) {
assert pref2 != null;
pref2.setVisible(true);
} else {
assert pref2 != null;
pref2.setVisible(false);
pref3.setEnabled(false);
pref3.setChecked(true);
setMTTCG(activity, true);
}
}
ListPreference cpuListPreference = (ListPreference) findPreference("cpu");
if (cpuListPreference != null) {
String arch = getArch(activity);
String[] cpuValues_i386 = getResources().getStringArray(R.array.cpuValues_i386);
List<String> cpuValuesList_i386 = Arrays.asList(cpuValues_i386);
String[] cpuLabels_i386 = getResources().getStringArray(R.array.cpuLabels_i386);
List<String> cpuLabels_list_i386 = Arrays.asList(cpuLabels_i386);
String[] cpuValues_x86_64 = getResources().getStringArray(R.array.cpuValues_x86_64);
List<String> cpuValuesList_x86_64 = Arrays.asList(cpuValues_x86_64);
String[] cpuLabels_x86_64 = getResources().getStringArray(R.array.cpuLabels_x86_64);
List<String> cpuLabels_list_x86_64 = Arrays.asList(cpuLabels_x86_64);
String[] cpuValues_arm64 = getResources().getStringArray(R.array.cpuValues_arm64);
List<String> cpuValuesList_arm64 = Arrays.asList(cpuValues_arm64);
String[] cpuLabels_arm64 = getResources().getStringArray(R.array.cpuLabels_arm64);
List<String> cpuLabels_list_arm64 = Arrays.asList(cpuLabels_arm64);
String[] cpuValues_ppc = getResources().getStringArray(R.array.cpuValues_ppc);
List<String> cpuValuesList_ppc = Arrays.asList(cpuValues_ppc);
String[] cpuLabels_ppc = getResources().getStringArray(R.array.cpuLabels_ppc);
List<String> cpuLabels_list_ppc = Arrays.asList(cpuLabels_ppc);
if (Objects.equals(arch, "I386")) {
cpuListPreference.setEntries(R.array.cpuLabels_i386);
cpuListPreference.setEntryValues(R.array.cpuValues_i386);
// Optionally, if you want to set a default value programmatically
cpuListPreference.setValue("qemu32"); // You can set this to whatever default you need
cpuListPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
} else if (Objects.equals(arch, "X86_64")) {
cpuListPreference.setEntries(R.array.cpuLabels_x86_64);
cpuListPreference.setEntryValues(R.array.cpuValues_x86_64);
// Optionally, if you want to set a default value programmatically
cpuListPreference.setValue("qemu64"); // You can set this to whatever default you need
cpuListPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
} else if (Objects.equals(arch, "ARM64")) {
cpuListPreference.setEntries(R.array.cpuLabels_arm64);
cpuListPreference.setEntryValues(R.array.cpuValues_arm64);
// Optionally, if you want to set a default value programmatically
cpuListPreference.setValue("arm926"); // You can set this to whatever default you need
cpuListPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
} else if (Objects.equals(arch, "POWERPC")) {
cpuListPreference.setEntries(R.array.cpuLabels_ppc);
cpuListPreference.setEntryValues(R.array.cpuValues_ppc);
// Optionally, if you want to set a default value programmatically
cpuListPreference.setValue("601_v1"); // You can set this to whatever default you need
cpuListPreference.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
}
}
/*Preference pref = findPreference("customMemory");
if (pref != null) {
@ -335,30 +419,20 @@ public class MainSettingsManager extends AppCompatActivity
public void onResume() {
super.onResume();
onMemory();
if (SDK_INT > 33)
findPreference("sharedFolder").setEnabled(false);
}
@Override
public void onPause() {
super.onPause();
onMemory();
if (SDK_INT > 33)
findPreference("sharedFolder").setEnabled(false);
}
private void onArch() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent startActivity = new Intent(getContext(), SplashActivity.class);
int pendingIntentId = 123456;
PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager mgr = (AlarmManager) MainSettingsManager.activity.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);
System.exit(0);
activity.finish();
startActivity(new Intent(activity, SplashActivity.class));
}
}, 300);
}
@ -367,8 +441,6 @@ public class MainSettingsManager extends AppCompatActivity
public void onCreatePreferences(Bundle bundle, String root_key) {
// Load the Preferences from the XML file
setPreferencesFromResource(R.xml.qemu, root_key);
if (SDK_INT > 33)
findPreference("sharedFolder").setEnabled(false);
}
@Override
@ -799,10 +871,10 @@ public class MainSettingsManager extends AppCompatActivity
return prefs.getString("customParams", "");
}
public static void setSharedFolder(Activity activity, boolean customParams) {
public static void setSharedFolder(Activity activity, boolean enable) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean("customParams", customParams);
edit.putBoolean("sharedFolder", enable);
edit.apply();
}

View file

@ -314,7 +314,7 @@ public class MainVNCActivity extends VncCanvasActivity {
MainService.stopService();
Terminal vterm = new Terminal(activity);
vterm.executeShellCommand("killall qemu-system-x86_64");
vterm.executeShellCommand("killall qemu-system-*", false, activity);
// Finish the activity
activity.finish();

View file

@ -35,21 +35,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
switch (key) {
case "modeNight":
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent startActivity = new Intent(getContext(), SplashActivity.class);
int pendingIntentId = 123456;
PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager mgr = (AlarmManager) MainSettingsManager.activity.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);
System.exit(0);
}
}, 300);
getActivity().finish();
startActivity(new Intent(getActivity(), SplashActivity.class));
break;
case "customMemory":
if (prefs.getBoolean("customMemory", false))

View file

@ -19,10 +19,10 @@ import java.util.Objects;
public class AppConfig {
// App Config
public static final String vectrasVersion = "2.9.1";
public static final String vectrasWebsite = "https://vectras.netlify.com/";
public static final String vectrasHelp = "https://vectras.netlify.app/how";
public static final String vectrasRaw = "https://raw.githubusercontent.com/epicstudios856/Vectras-windows-emulator/main/";
public static final String vectrasVersion = "2.9.0";
public static final String vectrasWebsite = "https://vectrasvm.blackstorm.cc/";
public static final String vectrasHelp = "https://vectrasvm.blackstorm.cc/how.html";
public static final String vectrasRaw = "https://vectrasvm.blackstorm.cc/vectras-vm/data/";
public static final String vectrasLicense = vectrasRaw + "LICENSE.md";
public static final String vectrasPrivacy = vectrasRaw + "PRIVACYANDPOLICY.md";
public static final String vectrasTerms = vectrasRaw + "TERMSOFSERVICE.md";
@ -31,7 +31,6 @@ public class AppConfig {
public static final String updateJson = vectrasRaw + "UpdateConfig.json";
public static final String blogJson = vectrasRaw + "news_list.json";
public static final String storeJson = vectrasRaw + "store_list.json";
public static final String vectrasPkg = vectrasWebsite + "download";
public static final String releaseUrl = "https://vectrasvm.blackstorm.cc/vectras-vm/Releases/";
@ -45,7 +44,7 @@ public class AppConfig {
return vectrasRaw + "roms-x86_64.json";
} else if (Objects.equals(MainSettingsManager.getArch(activity), "I386")) {
return vectrasRaw + "roms-i386.json";
} else if (Objects.equals(MainSettingsManager.getArch(activity), "ARM")) {
} else if (Objects.equals(MainSettingsManager.getArch(activity), "ARM64")) {
return vectrasRaw + "roms-aarch64.json";
} else if (Objects.equals(MainSettingsManager.getArch(activity), "PPC")) {
return vectrasRaw + "roms-ppc.json";
@ -60,10 +59,9 @@ public class AppConfig {
return activity.getExternalFilesDir("data") + "/Vectras";
//return FileUtils.getExternalFilesDirectory(activity).getPath();
}
;
public static final String sharedFolder = FileUtils.getExternalFilesDirectory(MainActivity.activity).getPath() + "/SharedFolder/";
public static final String basefiledir = datadirpath(SplashActivity.activity) + "/.qemu/";
public static final String maindirpath = datadirpath(SplashActivity.activity) + "/";
public static final String maindirpath = FileUtils.getExternalFilesDirectory(SplashActivity.activity).getPath() + "/";
public static final String sharedFolder = maindirpath + "SharedFolder/";
public static final String downloadsFolder = maindirpath + "Downloads/";
}

View file

@ -39,6 +39,7 @@ import com.google.android.gms.ads.initialization.OnInitializationCompleteListene
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.vectras.qemu.MainSettingsManager;
import com.vectras.vm.Fragment.CreateImageDialogFragment;
import com.vectras.vm.MainRoms.DataMainRoms;
import com.vectras.vm.logger.VectrasStatus;
import com.vectras.vm.utils.FileUtils;
@ -67,7 +68,11 @@ import java.util.zip.ZipInputStream;
public class CustomRomActivity extends AppCompatActivity {
public TextInputEditText title, icon, drive, cdrom, qemu;
public static TextInputEditText title;
public TextInputEditText icon;
public static TextInputEditText drive;
public TextInputEditText cdrom;
public TextInputEditText qemu;
public Button addRomBtn;
public ProgressBar loadingPb;
@ -218,6 +223,16 @@ public class CustomRomActivity extends AppCompatActivity {
startActivityForResult(intent, 1002);
}
});
driveLayout.setEndIconOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CreateImageDialogFragment dialogFragment = new CreateImageDialogFragment();
dialogFragment.customRom = true;
dialogFragment.show(getSupportFragmentManager(), "CreateImageDialogFragment");
}
});
View.OnClickListener cdromClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {

View file

@ -0,0 +1,111 @@
package com.vectras.vm.Fragment;
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.material.textfield.TextInputEditText;
import com.vectras.qemu.Config;
import com.vectras.vm.AppConfig;
import com.vectras.vm.CustomRomActivity;
import com.vectras.vm.R;
import com.vectras.vm.utils.FileUtils;
import com.vectras.vterm.Terminal;
public class CreateImageDialogFragment extends DialogFragment {
public boolean customRom = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.create_vhd, container, false);
return view;
}
// If you want to style the dialog to have no title or to adjust the width, etc., override onCreateDialog.
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.MainDialogTheme);
builder.setTitle("Create Image");
View view = getActivity().getLayoutInflater().inflate(R.layout.create_vhd, null);
TextInputEditText imageSize = view.findViewById(R.id.size);
TextInputEditText imageName = view.findViewById(R.id.name);
if (customRom)
imageName.setText(CustomRomActivity.title.getText().toString());
TextView createPath = view.findViewById(R.id.createPath);
createPath.setText(FileUtils.getExternalFilesDirectory(getActivity()).getPath() + "/QCOW2/");
if (customRom)
createPath.append(CustomRomActivity.title.getText().toString() + ".qcow2");
Button createQcow2Btn = view.findViewById(R.id.createQcow2Btn);
TextWatcher afterTextChangedListener = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ignore
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (isFilled(imageName) && isFilled(imageSize)) {
createQcow2Btn.setEnabled(true);
} else {
createQcow2Btn.setEnabled(false);
}
createPath.setText(FileUtils.getExternalFilesDirectory(getActivity()).getPath() + "/QCOW2/" + imageName.getText().toString() + ".qcow2");
}
@Override
public void afterTextChanged(Editable s) {
if (isFilled(imageName) && isFilled(imageSize))
createQcow2Btn.setEnabled(true);
else
createQcow2Btn.setEnabled(false);
}
};
imageName.addTextChangedListener(afterTextChangedListener);
imageSize.addTextChangedListener(afterTextChangedListener);
createQcow2Btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Terminal vterm = new Terminal(getActivity());
vterm.executeShellCommand("qemu-img create -f qcow2 " + FileUtils.getExternalFilesDirectory(getActivity()).getPath() + "/QCOW2/" + imageName.getText().toString() + ".qcow2 " +
imageSize.getText().toString() + "G", true, getActivity());
if (customRom)
CustomRomActivity.drive.setText(FileUtils.getExternalFilesDirectory(getActivity()).getPath() + "/QCOW2/" + imageName.getText().toString() + ".qcow2");
}
});
builder.setView(view);
return builder.create();
}
private boolean isFilled(TextInputEditText TXT) {
if (TXT.getText().toString().trim().length() > 0)
return true;
else
return false;
}
}

View file

@ -69,20 +69,21 @@ public class HomeFragment extends Fragment {
public MainActivity activity;
public static JSONArray jArray;
public static List<DataMainRoms> data;
private SwipeRefreshLayout refreshRoms;
/*private ImageButton mStop;
private ImageButton mRestart;*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
// TODO show the text view in @layout/home_fragment if list empty
activity = MainActivity.activity;
view = inflater.inflate(R.layout.home_fragment, container, false);
romsLayout = view.findViewById(R.id.romsLayout);
SwipeRefreshLayout refreshRoms = view.findViewById(R.id.refreshRoms);
refreshRoms = view.findViewById(R.id.refreshRoms);
refreshRoms.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
@ -136,7 +137,6 @@ public class HomeFragment extends Fragment {
mMainAdapter = new AdapterMainRoms(MainActivity.activity, data);
mRVMainRoms.setAdapter(mMainAdapter);
mRVMainRoms.setLayoutManager(new GridLayoutManager(MainActivity.activity, 2));
} catch (JSONException e) {
Toast.makeText(MainActivity.activity, e.toString(), Toast.LENGTH_LONG).show();
}

View file

@ -1,11 +1,13 @@
package com.vectras.vm;
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
import static android.os.Build.VERSION.SDK_INT;
import static com.vectras.vm.utils.UIUtils.UIAlert;
import android.app.ActivityManager;
import android.app.Dialog;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -25,8 +27,10 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
@ -50,6 +54,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.google.android.material.appbar.AppBarLayout;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.android.material.elevation.SurfaceColors;
@ -66,6 +71,7 @@ import com.vectras.vm.logger.VectrasStatus;
import com.vectras.vm.utils.AppUpdater;
import com.vectras.vm.utils.FileUtils;
import com.vectras.vm.utils.UIUtils;
import com.vectras.vterm.Terminal;
import org.json.JSONArray;
import org.json.JSONException;
@ -97,6 +103,12 @@ public class MainActivity extends AppCompatActivity {
private AdRequest adRequest;
public DrawerLayout mainDrawer;
private String TAG = "MainActivity";
public static /**/LinearLayout extVncLayout;
public static AppBarLayout appbar;
public TextView totalRam;
public TextView usedRam;
public TextView freeRam;
private final Timer _timer = new Timer();
@Override
protected void onCreate(Bundle bundle) {
@ -105,6 +117,9 @@ public class MainActivity extends AppCompatActivity {
RamInfo.activity = this;
setContentView(R.layout.activity_main);
if (!MainSettingsManager.getVncExternal(activity))
clearNotifications();
setupFolders();
NotificationManager notificationManager = (NotificationManager) activity.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
@ -117,6 +132,29 @@ public class MainActivity extends AppCompatActivity {
SwipeRefreshLayout refreshRoms = findViewById(R.id.refreshRoms);
appbar = findViewById(R.id.appbar);
appbar.setExpanded(false);
extVncLayout = findViewById(R.id.extVnc);
TextView tvLogin = findViewById(R.id.tvLogin);
tvLogin.setText("LOGIN --> " + Config.defaultVNCHost + ":" + (5900 + Config.defaultVNCPort)/* + "\nPASSWORD --> " + Config.defaultVNCPasswd*/);
Button stopBtn = findViewById(R.id.stopBtn);
stopBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Stop the service
MainService.stopService();
Terminal vterm = new Terminal(activity);
vterm.executeShellCommand("killall qemu-system-*", false, activity);
extVncLayout.setVisibility(View.GONE);
appbar.setExpanded(false);
}
});
refreshRoms.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
@ -125,8 +163,7 @@ public class MainActivity extends AppCompatActivity {
refreshRoms.setRefreshing(false);
}
});
BottomAppBar bottomAppBar = findViewById(R.id.bottomAppBar_AppBarBottomActivity);
bottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
/*bottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
@ -140,13 +177,13 @@ public class MainActivity extends AppCompatActivity {
return false;
}
});
});*/
FloatingActionButton fabAdd = findViewById(R.id.fabAdd_AppBarBottomActivity);
fabAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(activity, RomsManagerActivity.class));
startActivity(new Intent(activity, CustomRomActivity.class));
}
});
Toolbar mainToolbar = (Toolbar) findViewById(R.id.toolbar);
@ -172,11 +209,16 @@ public class MainActivity extends AppCompatActivity {
int id = menuItem.getItemId();
if (id == R.id.navigation_item_info) {
startActivity(new Intent(activity, AboutActivity.class));
} else if (id == R.id.navigation_item_website) {
} if (id == R.id.navigation_item_help) {
String tw = AppConfig.vectrasWebsite;
Intent w = new Intent(Intent.ACTION_VIEW);
w.setData(Uri.parse(tw));
startActivity(w);
} else if (id == R.id.navigation_item_website) {
String tw = AppConfig.vectrasHelp;
Intent w = new Intent(Intent.ACTION_VIEW);
w.setData(Uri.parse(tw));
startActivity(w);
} else if (id == R.id.navigation_item_import_iso) {
if (new File(AppConfig.maindirpath + "/drive.iso").exists()) {
AlertDialog ad;
@ -191,7 +233,7 @@ public class MainActivity extends AppCompatActivity {
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
@ -218,7 +260,7 @@ public class MainActivity extends AppCompatActivity {
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
@ -238,7 +280,7 @@ public class MainActivity extends AppCompatActivity {
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
@ -283,7 +325,7 @@ public class MainActivity extends AppCompatActivity {
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
@ -303,7 +345,7 @@ public class MainActivity extends AppCompatActivity {
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
@ -348,7 +390,7 @@ public class MainActivity extends AppCompatActivity {
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
}
@ -472,6 +514,66 @@ public class MainActivity extends AppCompatActivity {
});
alertDialog.show();
}
totalRam = findViewById(R.id.totalRam);
usedRam = findViewById(R.id.usedRam);
freeRam = findViewById(R.id.freeRam);
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long freeMem = mi.availMem / 1048576L;
long totalMem = mi.totalMem / 1048576L;
long usedMem = totalMem - freeMem;
int freeRamInt = safeLongToInt(freeMem);
int totalRamInt = safeLongToInt(totalMem);
totalRam = findViewById(R.id.totalRam);
usedRam = findViewById(R.id.usedRam);
freeRam = findViewById(R.id.freeRam);
String vectrasMemory = String.valueOf(RamInfo.vectrasMemory());
TimerTask t = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ActivityManager.MemoryInfo miI = new ActivityManager.MemoryInfo();
ActivityManager activityManagerr = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManagerr.getMemoryInfo(miI);
long freeMemory = miI.availMem / 1048576L;
long totalMemory = miI.totalMem / 1048576L;
long usedMemory = totalMemory - freeMemory;
totalRam.setText("Total Memory: " + totalMemory + " MB");
usedRam.setText("Used Memory: " + usedMemory + " MB");
freeRam.setText("Free Memory: " + freeMemory + " MB (" + vectrasMemory + " used)");
ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setMax((int) totalMemory);
if (SDK_INT >= Build.VERSION_CODES.N) {
progressBar.setProgress((int) usedMemory, true);
} else {
progressBar.setProgress((int) usedMemory);
}
}
});
}
};
_timer.scheduleAtFixedRate(t, (int) (0), (int) (1000));
}
public static void clearNotifications() {
NotificationManager notificationManager = (NotificationManager) activity.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancelAll();
}
public static int safeLongToInt(long l) {
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
}
return (int) l;
}
public static PackageInfo getAppInfo(Context context) {
@ -578,8 +680,13 @@ public class MainActivity extends AppCompatActivity {
// Menu items
int id = item.getItemId();
if (id == R.id.installRoms) {
startActivity(new Intent(activity, RomsManagerActivity.class));
if (id == R.id.info) {
appbar = findViewById(R.id.appbar);
if (appbar.getTop() < 0)
appbar.setExpanded(true);
else
appbar.setExpanded(false);
} else if (id == R.id.arch) {
startActivity(new Intent(activity, SetArchActivity.class));
}
@ -621,8 +728,38 @@ public class MainActivity extends AppCompatActivity {
return false;
}
public static boolean checkSharedFolder() { //TODO: not work idk why
File folder = new File(AppConfig.sharedFolder);
File[] listOfFiles = folder.listFiles();
if (listOfFiles != null) {
for (File file : listOfFiles) {
if (file.isFile() && file.length() > 500 * 1024 * 1024) { // 500MB
return true;
}
}
}
return false;
}
public static void startVM(String vmName, String env) {
if (checkSharedFolder()) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle("Large File Detected");
builder.setMessage("One or more files in this folder are larger than 500MB, " +
"due qemu limits you can't use shared folder that's contains files larger than 500mb, " +
"please disable shared folder Settings>qemu or free some files from shared folder.");
builder.setPositiveButton("OK", (dialogInterface, i) -> dialogInterface.dismiss());
builder.create().show();
return;
}
boolean isRunning = isMyServiceRunning(MainService.class);
ProgressDialog progressDialog = new ProgressDialog(activity, R.style.MainDialogTheme);
progressDialog.setMessage("Booting up...");
progressDialog.setCancelable(false); // Make the dialog non-cancellable if you like
progressDialog.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
@ -630,21 +767,29 @@ public class MainActivity extends AppCompatActivity {
Intent serviceIntent = new Intent(activity, MainService.class);
MainService.env = env;
MainService.CHANNEL_ID = vmName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
activity.startForegroundService(serviceIntent);
} else {
activity.startService(serviceIntent);
}
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
if (MainSettingsManager.getVncExternal(MainActivity.activity)) {
extVncLayout.setVisibility(View.VISIBLE);
appbar.setExpanded(true);
} else {
activity.startActivity(new Intent(activity, MainVNCActivity.class));
}
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
//activity.startActivity(new Intent(activity, RemoteCanvasActivity.class));
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
//activity.startActivity(new Intent(activity, X11Activity.class));
}
progressDialog.dismiss();
}
}
}, 5000);
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
activity.startActivity(new Intent(activity, MainVNCActivity.class));
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
//activity.startActivity(new Intent(activity, RemoteCanvasActivity.class));
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
//activity.startActivity(new Intent(activity, X11Activity.class));
}
String[] params = env.split("\\s+");
VectrasStatus.logInfo("Params:");
Log.d("StartVM", "Params:");
@ -652,6 +797,7 @@ public class MainActivity extends AppCompatActivity {
VectrasStatus.logInfo(i + ": " + params[i]);
Log.d("StartVM", i + ": " + params[i]);
}
}
private void setupFolders() {
@ -677,12 +823,35 @@ public class MainActivity extends AppCompatActivity {
startActivity(new Intent(activity, MainVNCActivity.class));
}
public static boolean isServiceRunning(Class<?> serviceClass, Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (manager != null) {
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
}
return false;
}
public void onStart() {
super.onStart();
Log.d(TAG, "onStart");
loadDataVbi();
Config.ui = MainSettingsManager.getVmUi(activity);
TextView tvQemuArch = findViewById(R.id.qemuArch);
tvQemuArch.setText(MainSettingsManager.getArch(activity));
TextView tvIsRunning = findViewById(R.id.tvIsRunning);
boolean isMainServiceRunning = isServiceRunning(MainService.class, activity);
if (isMainServiceRunning)
tvIsRunning.setText(R.string.running);
else
tvIsRunning.setText(R.string.stopped);
//TEMPORARY FIX FOR VNC CLOSES
//TODO: FIND FIX FOR CRASHING
if (MainSettingsManager.getVmUi(activity).equals("VNC") && MainVNCActivity.started)
@ -728,7 +897,7 @@ public class MainActivity extends AppCompatActivity {
if (requestCode == 1004 && resultCode == RESULT_OK) {
Uri content_describer = ReturnedIntent.getData();
File selectedFilePath = new File(getPath(content_describer));
ProgressBar loading = findViewById(R.id.progressBar);
ProgressBar loading = findViewById(R.id.loading);
if (selectedFilePath.toString().endsWith(".iso")) {
loading.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
@ -780,7 +949,7 @@ public class MainActivity extends AppCompatActivity {
} else if (requestCode == 1005 && resultCode == RESULT_OK) {
Uri content_describer = ReturnedIntent.getData();
File selectedFilePath = new File(getPath(content_describer));
ProgressBar loading = findViewById(R.id.progressBar);
ProgressBar loading = findViewById(R.id.loading);
loading.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
@Override
@ -829,7 +998,7 @@ public class MainActivity extends AppCompatActivity {
} else if (requestCode == 1006 && resultCode == RESULT_OK) {
Uri content_describer = ReturnedIntent.getData();
File selectedFilePath = new File(getPath(content_describer));
ProgressBar loading = findViewById(R.id.progressBar);
ProgressBar loading = findViewById(R.id.loading);
loading.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
@Override
@ -878,7 +1047,7 @@ public class MainActivity extends AppCompatActivity {
} else if (requestCode == 122 && resultCode == RESULT_OK) {
Uri content_describer = ReturnedIntent.getData();
File selectedFilePath = new File(getPath(content_describer));
ProgressBar loading = findViewById(R.id.progressBar);
ProgressBar loading = findViewById(R.id.loading);
loading.setVisibility(View.VISIBLE);
new Thread(new Runnable() {
@Override

View file

@ -121,13 +121,13 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
final File jsonFile = new File(MainActivity.activity.getExternalFilesDir("data") + "/rom-data.json");
AlertDialog ad;
ad = new AlertDialog.Builder(MainActivity.activity).create();
ad.setTitle("Export Rom");
ad.setMessage("Are you sure?");
ad.setTitle(MainActivity.activity.getString(R.string.export_rom));
ad.setMessage(MainActivity.activity.getString(R.string.are_you_sure));
final TextInputLayout Description = new TextInputLayout(MainActivity.activity);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
Description.setHint("DESCRIPTION (html supported)");
Description.setHint(R.string.description_html_supported);
Description.setLayoutParams(lp);
Description.setPadding(10, 10, 10, 10);
final TextInputEditText DescriptionET = new TextInputEditText(MainActivity.activity);
@ -136,7 +136,7 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
LinearLayout.LayoutParams.MATCH_PARENT);
DescriptionET.setLayoutParams(lp2);
Description.addView(DescriptionET);
DescriptionET.setText("null");
DescriptionET.setText("");
DescriptionET.setInputType(InputType.TYPE_CLASS_TEXT);
DescriptionET.setSelectAllOnFocus(true);
ad.setView(Description);
@ -154,8 +154,8 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
SharedPreferences credentials = MainActivity.activity.getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE);
ProgressDialog progressDialog = new ProgressDialog(MainActivity.activity);
progressDialog.setTitle("Compressing CVBI");
progressDialog.setMessage("Please wait...");
progressDialog.setTitle(MainActivity.activity.getString(R.string.compressing_cvbi));
progressDialog.setMessage(MainActivity.activity.getString(R.string.please_wait_dialog));
progressDialog.setCancelable(false);
progressDialog.show(); // Showing Progress Dialog
Thread t = new Thread() {
@ -173,7 +173,7 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
@Override
public void run() {
progressDialog.cancel(); // cancelling Dialog.
UIUtils.UIAlert(MainActivity.activity, "ERROR!", e.toString());
UIUtils.UIAlert(MainActivity.activity, MainActivity.activity.getString(R.string.error), e.toString());
}
};
MainActivity.activity.runOnUiThread(runnable);
@ -182,7 +182,7 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
@Override
public void run() {
progressDialog.cancel(); // cancelling Dialog.}
UIUtils.UIAlert(MainActivity.activity, "DONE!", FileUtils.getExternalFilesDirectory(MainActivity.activity).getPath() + "/cvbi/" + current.itemName + ".cvbi");
UIUtils.UIAlert(MainActivity.activity, MainActivity.activity.getString(R.string.done), FileUtils.getExternalFilesDirectory(MainActivity.activity).getPath() + "/cvbi/" + current.itemName + ".cvbi");
}
};
MainActivity.activity.runOnUiThread(runnable);
@ -192,7 +192,7 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
t.start();
return;
});
ad.setButton(Dialog.BUTTON_NEGATIVE, "CLOSE", (dialog, which) -> {
ad.setButton(Dialog.BUTTON_NEGATIVE, MainActivity.activity.getString(R.string.close), (dialog, which) -> {
return;
});
ad.show();
@ -214,9 +214,9 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
public boolean onLongClick(View v) {
AlertDialog ad;
ad = new AlertDialog.Builder(MainActivity.activity, R.style.MainDialogTheme).create();
ad.setTitle("Remove " + current.itemName);
ad.setMessage("Are you sure?");
ad.setButton(Dialog.BUTTON_NEGATIVE, "REMOVE " + current.itemName, new DialogInterface.OnClickListener() {
ad.setTitle(MainActivity.activity.getString(R.string.remove)+ " " + current.itemName);
ad.setMessage(MainActivity.activity.getString(R.string.are_you_sure));
ad.setButton(Dialog.BUTTON_NEGATIVE, MainActivity.activity.getString(R.string.remove) + " " + current.itemName, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
File file = new File(current.itemPath);
File file2 = new File(current.itemDrv1);
@ -269,11 +269,11 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
} catch (Exception e) {
UIUtils.toastLong(MainActivity.activity, e.toString());
}
UIUtils.toastLong(MainActivity.activity, current.itemName + " are removed successfully!");
UIUtils.toastLong(MainActivity.activity, current.itemName + context.getString(R.string.are_removed_successfully));
return;
}
});
ad.setButton(Dialog.BUTTON_POSITIVE, "CANCEL", new DialogInterface.OnClickListener() {
ad.setButton(Dialog.BUTTON_POSITIVE, MainActivity.activity.getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
@ -320,9 +320,9 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
public void onClick(View v) {
AlertDialog ad;
ad = new AlertDialog.Builder(MainActivity.activity, R.style.MainDialogTheme).create();
ad.setTitle("Remove " + title);
ad.setMessage("Are you sure?");
ad.setButton(Dialog.BUTTON_NEGATIVE, "REMOVE " + title, new DialogInterface.OnClickListener() {
ad.setTitle(MainActivity.activity.getString(R.string.remove) + " " + title);
ad.setMessage(MainActivity.activity.getString(R.string.are_you_sure));
ad.setButton(Dialog.BUTTON_NEGATIVE, MainActivity.activity.getString(R.string.remove) + " " + title, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
File file = new File(path);
try {
@ -345,11 +345,11 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
} catch (Exception e) {
UIUtils.toastLong(MainActivity.activity, e.toString());
}
UIUtils.toastLong(MainActivity.activity, title + " are removed successfully!");
UIUtils.toastLong(MainActivity.activity, title + MainActivity.activity.getString(R.string.are_removed_successfully));
return;
}
});
ad.setButton(Dialog.BUTTON_POSITIVE, "CANCEL", new DialogInterface.OnClickListener() {
ad.setButton(Dialog.BUTTON_POSITIVE, MainActivity.activity.getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}

View file

@ -49,7 +49,7 @@ public class MainService extends Service {
Terminal vterm = new Terminal(this);
//vterm.executeShellCommand("chmod 770 /run/pulse -R");
//vterm.executeShellCommand("pulseaudio --system --disallow-exit --disallow-module-loading --daemonize --log-level=debug --log-time=1");
vterm.executeShellCommand(env);
vterm.executeShellCommand(env, true, MainActivity.activity);
}
} else
Log.e(TAG, "env is null");

View file

@ -129,9 +129,9 @@ public class RomsManagerActivity extends AppCompatActivity {
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
@ -250,7 +250,8 @@ public class RomsManagerActivity extends AppCompatActivity {
data = new ArrayList<>();
try {
JSONArray jArray = new JSONArray(FileUtils.readFromFile(activity, new File(getExternalFilesDir("data") + "roms.json")));
String fileName = "roms-" + MainSettingsManager.getArch(activity) + ".json";
JSONArray jArray = new JSONArray(FileUtils.readFromFile(activity, new File(getExternalFilesDir("data") + "/" + fileName)));
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < jArray.length(); i++) {

View file

@ -24,48 +24,40 @@ public class SetArchActivity extends AppCompatActivity implements View.OnClickLi
mHandler = new Handler();
setContentView(R.layout.activity_set_arch);
activity = this;
Button arch86 = findViewById(R.id.archx86);
Button archarm = findViewById(R.id.archarm);
Button archi386 = findViewById(R.id.archi386);
Button archx86_64 = findViewById(R.id.archx86_64);
Button archarm64 = findViewById(R.id.archarm64);
Button archppc = findViewById(R.id.archppc);
Button web = findViewById(R.id.webBtn);
arch86.setOnClickListener(this);
archarm.setOnClickListener(this);
archi386.setOnClickListener(this);
archx86_64.setOnClickListener(this);
archarm64.setOnClickListener(this);
archppc.setOnClickListener(this);
web.setOnClickListener(this);
}
public void onClick(View v) {
int id = v.getId();
if (id == R.id.archx86) {
if (id == R.id.archi386) {
MainSettingsManager.setArch(this, "I386");
finish();
startActivity(new Intent(this, SplashActivity.class));
} else if (id == R.id.archx86_64) {
MainSettingsManager.setArch(this, "X86_64");
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent startActivity = new Intent(activity, SplashActivity.class);
int pendingIntentId = 123456;
PendingIntent pendingIntent = PendingIntent.getActivity(activity, pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
finish();
startActivity(new Intent(this, SplashActivity.class));
} else if (id == R.id.archarm64) {
MainSettingsManager.setArch(this, "ARM64");
AlarmManager mgr = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);
finish();
startActivity(new Intent(this, SplashActivity.class));
} else if (id == R.id.archppc) {
MainSettingsManager.setArch(this, "PPC");
System.exit(0);
}
}, 300);
} else if (id == R.id.archarm) {
MainSettingsManager.setArch(this, "ARM");
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent startActivity = new Intent(activity, SplashActivity.class);
int pendingIntentId = 123456;
PendingIntent pendingIntent = PendingIntent.getActivity(activity, pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager mgr = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);
System.exit(0);
}
}, 300);
finish();
startActivity(new Intent(this, SplashActivity.class));
} else if (id == R.id.webBtn) {
String qe = "https://www.qemu.org/";
Intent q = new Intent(Intent.ACTION_VIEW);

View file

@ -351,7 +351,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
executeShellCommand("set -e;" +
" echo 'Starting setup...';" +
" apk update;" +
" apk add tar tigervnc dwm libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
" 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;" +
" tar -xzvf " + tarPath + " -C /;" +

View file

@ -57,10 +57,7 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
SharedPreferences prefs = getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE);
try {
if (checkConnection(activity))
new DownloadFileAsync().execute(AppConfig.romsJson(activity));
else
new Handler().postDelayed(activity, 3000);
new Handler().postDelayed(activity, 3000);
} catch (Exception e) {
throw new RuntimeException(e);
}/*
@ -102,11 +99,21 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
cvbiDir.mkdirs();
}
File sharedDir = new File(FileUtils.getExternalFilesDirectory(activity).getPath() + "/SharedFolder");
File sharedDir = new File(AppConfig.sharedFolder);
if (!sharedDir.exists()) {
sharedDir.mkdirs();
}
File downloadsDir = new File(AppConfig.downloadsFolder);
if (!downloadsDir.exists()) {
downloadsDir.mkdirs();
}
File qcow2Dir = new File(FileUtils.getExternalFilesDirectory(activity).getPath() + "/QCOW2");
if (!qcow2Dir.exists()) {
qcow2Dir.mkdirs();
}
File jsonFile = new File(AppConfig.maindirpath
+ "roms-data.json");
if (!jsonFile.exists())
@ -163,7 +170,7 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
}
com.vectras.qemu.utils.FileInstaller.installFiles(activity, false);
com.vectras.qemu.utils.FileInstaller.installFiles(activity, true);
}
public void onStart() {
@ -240,9 +247,9 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
int lenghtOfFile = conexion.getContentLength();
Log.d(TAG, "Lenght of file: " + lenghtOfFile);
String fileName = "roms.json";
String fileName = "roms-" + MainSettingsManager.getArch(activity) + ".json";
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(getExternalFilesDir("data") + fileName);
OutputStream output = new FileOutputStream(getExternalFilesDir("data") + "/" + fileName);
byte data[] = new byte[1024];

View file

@ -11,23 +11,33 @@ import com.vectras.vm.utils.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
public class StartVM {
public static String cache;
static String[] qemu = new String[]{"qemu-system-x86_64"};
public static String env(Activity activity, String extras, String img) {
String filesDir = activity.getFilesDir().getAbsolutePath();
String[] qemu = new String[0];
ArrayList<String> params = new ArrayList<>(Arrays.asList(qemu));
if (MainSettingsManager.getArch(activity).equals("I386"))
params.add("qemu-system-i386");
else if (MainSettingsManager.getArch(activity).equals("X86_64"))
params.add("qemu-system-x86_64");
else if (MainSettingsManager.getArch(activity).equals("ARM64"))
params.add("qemu-system-aarch64");
else if (MainSettingsManager.getArch(activity).equals("PPC"))
params.add("qemu-system-ppc");
String ifType = MainSettingsManager.getIfType(activity);
String cdrom;
String hdd1;
String hdd2;
String hdd0 = "-drive";
hdd0 += " index=0";
@ -58,22 +68,15 @@ public class StartVM {
params.add(hdd1);
}
File hdd2File = new File(filesDir + "/data/Vectras/hdd2.qcow2");
if (hdd2File.exists()) {
hdd2 = "-drive";
hdd2 += " index=3";
hdd2 += ",media=disk";
hdd2 += ",if=" + ifType;
hdd2 += ",file='" + hdd2File.getPath() + "'";
params.add(hdd2);
if (MainSettingsManager.getSharedFolder(activity)) {
String driveParams = "-drive ";
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);
}
/*if (MainSettingsManager.getSharedFolder(activity)) {
params.add("-net user,smb='" + FileUtils.getExternalFilesDirectory(activity).getPath() + "/SharedFolder" + "'");
params.add("-net nic,model=virtio");
}*/
boolean kvm = MainSettingsManager.getKvm(activity);
boolean avx = MainSettingsManager.getAvx(activity);
@ -102,12 +105,16 @@ public class StartVM {
//params.add(soundDevice);
String bios = "-bios ";
bios += AppConfig.basefiledir + "/bios-vectras.bin";
bios += AppConfig.basefiledir + "bios-vectras.bin";
String machine = "-M ";
machine += "pc";
params.add(machine);
if (Objects.equals(MainSettingsManager.getArch(activity), "X86_64")) {
machine += "pc";
params.add(machine);
} else if (Objects.equals(MainSettingsManager.getArch(activity), "ARM64")) {
machine += "virt";
params.add(machine);
}
params.add("-overcommit");
params.add("mem-lock=off");
@ -135,23 +142,16 @@ public class StartVM {
String vncStr = "-vnc ";
params.add(vncStr);
// Allow connections only from localhost using localsocket without a password
//params.add(Config.defaultVNCHost+":" + Config.defaultVNCPort);
String qmpParams = "unix:";
qmpParams += Config.getLocalVNCSocketPath();
params.add(qmpParams);
if (MainSettingsManager.getVncExternal(activity))
params.add(Config.defaultVNCHost + ":" + Config.defaultVNCPort);
else {
String qmpParams = "unix:";
qmpParams += Config.getLocalVNCSocketPath();
params.add(qmpParams);
}
params.add("-monitor");
params.add("vc");
//XXX: monitor, serial, and parallel display crashes cause SDL doesn't support more than 1 window
params.add("-monitor");
params.add("none");
params.add("-serial");
params.add("none");
params.add("-parallel");
params.add("none");
} else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
String spiceStr = "-spice ";
spiceStr += "port=6999,disable-ticketing=on";

View file

@ -53,7 +53,7 @@ public class AdapterStore extends RecyclerView.Adapter<RecyclerView.ViewHolder>
MyHolder myHolder = (MyHolder) holder;
final DataStore current = data.get(position);
myHolder.textName.setText(current.itemName);
myHolder.textSize.setText("Size: " + current.itemSize);
myHolder.textSize.setText(MainActivity.activity.getString(R.string.size) + current.itemSize);
Glide.with(StoreActivity.activity).load(current.itemIcon).into(myHolder.ivIcon);
Animation animation;
animation = AnimationUtils.loadAnimation(MainActivity.activity, android.R.anim.slide_in_left);

View file

@ -219,7 +219,7 @@ public class StoreActivity extends AppCompatActivity {
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, 0, 0, "IMPORT FILES").setShortcut('3', 'c').setIcon(R.drawable.input_circle).setShowAsAction(1);
//menu.add(0, 0, 0, "IMPORT FILES").setShortcut('3', 'c').setIcon(R.drawable.input_circle).setShowAsAction(1);
return true;
}

View file

@ -168,8 +168,8 @@ public class StoreItemActivity extends AppCompatActivity {
}
in.close();
} catch (Exception e) {
itemDesc.setText("no internet connection");
UIUtils.toastLong(StoreItemActivity.this, "check your internet connection");
itemDesc.setText(R.string.no_internet_connection);
UIUtils.toastLong(StoreItemActivity.this, getString(R.string.check_your_internet_connection));
Log.d("VECTRAS", e.toString());
}
@ -220,7 +220,7 @@ public class StoreItemActivity extends AppCompatActivity {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this, R.style.MainDialogTheme);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setMessage(getString(R.string.downloading_file));
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
@ -248,10 +248,10 @@ public class StoreItemActivity extends AppCompatActivity {
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d(TAG, "Lenght of file: " + lenghtOfFile);
Log.d(TAG, getString(R.string.lenght_of_file) + lenghtOfFile);
String fileName = URLUtil.guessFileName(link,null,null);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(AppConfig.sharedFolder+fileName);
OutputStream output = new FileOutputStream(AppConfig.downloadsFolder+fileName);
byte data[] = new byte[1024];
@ -282,9 +282,9 @@ public class StoreItemActivity extends AppCompatActivity {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
AlertDialog ad;
ad = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create();
ad.setTitle("Downloaded Successfully!");
ad.setTitle(getString(R.string.downloaded_successfully));
String fileName = URLUtil.guessFileName(link,null,null);
ad.setMessage("Downloaded to path: "+AppConfig.sharedFolder+fileName+" boot vectras to check your downloads in QEMU VFAT partition.");
ad.setMessage(getString(R.string.downloaded_to_path)+AppConfig.downloadsFolder+fileName);
ad.setButton(Dialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;

View file

@ -25,6 +25,7 @@ import android.widget.ScrollView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.content.res.ResourcesCompat;
import com.google.android.material.color.DynamicColors;
import com.vectras.qemu.MainSettingsManager;
@ -40,11 +41,13 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
public class VectrasApp extends Application {
@ -71,6 +74,28 @@ public class VectrasApp extends Application {
}
setModeNight(this);
DynamicColors.applyToActivitiesIfAvailable(this);
Locale locale = Locale.getDefault();
String language = locale.getLanguage();
if (language.contains("ar")) {
overrideFont("DEFAULT", R.font.cairo_regular);
} else {
overrideFont("DEFAULT", R.font.josefin_sans);
}
}
public void overrideFont(String defaultFontNameToOverride, int customFontResourceId) {
try {
Typeface customFontTypeface = ResourcesCompat.getFont(getApplicationContext(), customFontResourceId);
final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
defaultFontTypefaceField.setAccessible(true);
defaultFontTypefaceField.set(null, customFontTypeface);
} catch (Exception e) {
Log.e("overrideFont", "Failed to override font", e);
}
}
private void setModeNight(Context context) {

View file

@ -1,26 +1,11 @@
package com.vectras.vterm;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.core.app.NotificationCompat;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.vectras.vterm.view.ZoomableTextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
@ -33,6 +18,9 @@ import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import com.vectras.vm.MainActivity;
import com.vectras.vm.R;
public class Terminal {
private static final String TAG = "Vterm";
private Context context;
@ -63,8 +51,22 @@ public class Terminal {
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) {
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
@ -93,20 +95,17 @@ public class Terminal {
processBuilder.environment().put("QEMU_AUDIO_DRV", "sdl");
processBuilder.environment().put("SDL_VIDEODRIVER", "x11");
// Example PRoot command; replace 'libproot.so' and other paths as needed
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",
"--rootfs=" + filesDir + "/distro", // Path to the rootfs
"--bind=/dev",
"--bind=/proc",
"--bind=/sys",
"--bind=/sdcard",
"--bind=/storage",
"--bind=/data",
"--cwd=/root",
"/bin/sh",
"--login" // The shell to execute inside PRoot
};
@ -128,29 +127,47 @@ public class Terminal {
String line;
while ((line = reader.readLine()) != null) {
Log.d(TAG, line);
com.vectras.vm.logger.VectrasStatus.logError("<font color='red'>Vterm ERROR: >"+ line+"</font>");
com.vectras.vm.logger.VectrasStatus.logError("<font color='yellow'>VTERM: >"+ line+"</font>");
output.append(line).append("\n");
}
// 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>");
com.vectras.vm.logger.VectrasStatus.logError("<font color='red'>VTERM ERROR: >"+ line+"</font>");
output.append(line).append("\n");
}
// Clean up
reader.close();
errorReader.close();
// Wait for the qemuProcess to finish
qemuProcess.waitFor();
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) {
// Handle exceptions by printing the stack trace in the terminal output
final String errorMessage = e.getMessage();
Log.e("Vterm ERROR:", errorMessage);
//com.vectras.vm.logger.VectrasStatus.logError("<font color='red'>Vterm ERROR: >"+ errorMessage+"</font>");
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();
showDialog(finalOutput.isEmpty() ? finalErrors : finalOutput, dialogActivity);
}
});
}
}).start(); // Execute the command in a separate thread to prevent blocking the UI thread
}).start();
}
private boolean checkInstallation() {

View file

@ -83,9 +83,12 @@ public class TerminalBottomSheetDialog {
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
activity.runOnUiThread(() -> appendTextAndScroll(commandInput.getText().toString() + "\n"));
executeShellCommand(commandInput.getText().toString());
commandInput.setText("");
commandInput.requestFocus();
activity.runOnUiThread(() -> {
commandInput.requestFocus(); // Request focus again
});
return true;
}
return false;
@ -173,22 +176,19 @@ public class TerminalBottomSheetDialog {
processBuilder.environment().put("QEMU_AUDIO_DRV", "sdl");
processBuilder.environment().put("SDL_VIDEODRIVER", "x11");
// Example PRoot command; replace 'libproot.so' and other paths as needed
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",
"--rootfs=" + filesDir + "/distro", // Path to the rootfs
"--bind=/dev",
"--bind=/proc",
"--bind=/sys",
"--bind=/sdcard",
"--bind=/storage",
"--bind=/data",
"--cwd=/root",
"/bin/sh",
"--login"// The shell to execute inside PRoot
"--login" // The shell to execute inside PRoot
};
processBuilder.command(prootCommand);
@ -231,7 +231,7 @@ public class TerminalBottomSheetDialog {
}
}).start(); // Execute the command in a separate thread to prevent blocking the UI thread
else
new AlertDialog.Builder(activity)
new AlertDialog.Builder(activity, R.style.MainDialogTheme)
.setTitle("Error!")
.setMessage("Verify that \"setupFiles()\" is working properly in onCreate().")
.setCancelable(false)