diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 1604e6d..646789f 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -1,18 +1,6 @@ - - - - - - - - - - - - diff --git a/app/build.gradle b/app/build.gradle index c7504e7..6ac037f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ android { applicationId "com.vectras.vm" minSdk 21 targetSdk 34 - versionCode 5 - versionName "2.1" + versionCode 6 + versionName "2.2" ndk { abiFilters "armeabi-v7a","arm64-v8a", "x86", "x86_64" } testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/android/androidVNC/VncCanvasActivity.java b/app/src/main/java/android/androidVNC/VncCanvasActivity.java index f36ffd3..3c21bfa 100644 --- a/app/src/main/java/android/androidVNC/VncCanvasActivity.java +++ b/app/src/main/java/android/androidVNC/VncCanvasActivity.java @@ -44,12 +44,11 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; -import android.widget.Toast; import android.widget.ZoomControls; import com.antlersoft.android.bc.BCFactory; import com.vectras.qemu.Config; -import com.vectras.qemu.MainActivityCommon; +import com.vectras.vm.MainActivity; import com.vectras.vm.R; import com.vectras.vm.utils.UIUtils; @@ -778,7 +777,7 @@ public void onCreate(Bundle icicle) { // connection.setAddress(host.substring(0, host.indexOf(':'))); // } } - connection.setPassword(MainActivityCommon.getVnc_passwd()); + connection.setPassword(MainActivity.getVnc_passwd()); setContentView(); vncCanvas = (VncCanvas) findViewById(R.id.vnc_canvas); diff --git a/app/src/main/java/com/vectras/qemu/MainActivityCommon.java b/app/src/main/java/com/vectras/qemu/MainActivityCommon.java deleted file mode 100644 index 83e400e..0000000 --- a/app/src/main/java/com/vectras/qemu/MainActivityCommon.java +++ /dev/null @@ -1,676 +0,0 @@ -package com.vectras.qemu; - -import android.androidVNC.RfbProto; -import android.androidVNC.VncCanvas; -import android.app.Activity; -import android.app.NotificationManager; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Environment; -import android.os.Handler; -import android.os.Looper; -import android.os.StrictMode; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.widget.EditText; -import android.widget.TextView; - -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; - -import com.vectras.qemu.jni.StartVM; -import com.vectras.qemu.utils.FileInstaller; -import com.vectras.qemu.utils.FileUtils; -import com.vectras.qemu.utils.Machine; -import com.vectras.qemu.utils.QmpClient; -import com.vectras.vm.R; -import com.vectras.vm.utils.UIUtils; - -import java.io.File; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Enumeration; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class MainActivityCommon { - - public static VMStatus currStatus = VMStatus.Ready; - public static boolean vmStarted = false; - public static StartVM vmexecutor; - public static String vnc_passwd = "vectras"; - public static int vnc_allow_external = 1; - public static int qmp_allow_external = 0; - public static ProgressDialog progDialog; - public static View parent; - public static InstallerTask installerTaskTask; - public static boolean timeQuit = false; - public static Object lockTime = new Object(); - - public static final String TAG = "VECTRAS"; - - public static AppCompatActivity activity = null; - - public static boolean libLoaded; - - - static public void onInstall(boolean force) { - FileInstaller.installFiles(activity, force); - } - - public static String getVnc_passwd() { - return vnc_passwd; - } - - public static void setVnc_passwd(String vnc_passwd) { - vnc_passwd = vnc_passwd; - } - - public static String getLocalIpAddress() { - try { - for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { - NetworkInterface intf = en.nextElement(); - for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) { - return inetAddress.getHostAddress().toString(); - } - } - } - } catch (SocketException ex) { - ex.printStackTrace(); - } - return null; - } - - // Start calling the JNI interface - public static void startvm(Activity activity, int UI) { - QmpClient.allow_external = (qmp_allow_external == 1); - vmexecutor.qmp_allow_external = qmp_allow_external; - - if (UI == Config.UI_VNC) { - // disable sound card with VNC - vmexecutor.enablevnc = 1; - vmexecutor.enablespice = 0; - vmexecutor.sound_card = null; - vmexecutor.vnc_allow_external = vnc_allow_external; - RfbProto.allow_external = (vnc_allow_external == 1); - vmexecutor.vnc_passwd = vnc_passwd; - } else if (UI == Config.UI_SDL) { - vmexecutor.enablevnc = 0; - vmexecutor.enablespice = 0; - } else if (UI == Config.UI_SPICE) { - vmexecutor.vnc_allow_external = vnc_allow_external; - vmexecutor.vnc_passwd = vnc_passwd; - vmexecutor.enablevnc = 0; - vmexecutor.enablespice = 1; - } - vmexecutor.startvm(activity, UI); - - } - - - public static void cleanup() { - - vmStarted = false; - - //XXX flush and close all file descriptors if we haven't already - FileUtils.close_fds(); - - ////XXX; we wait till fds flush and close - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - //set the exit code - MainSettingsManager.setExitCode(activity, 1); - - //XXX: SDL seems to lock the keyboard events - // unless we finish the starting activity - activity.finish(); - - Log.v(TAG, "Exit"); - //XXX: We exit here to force unload the native libs - System.exit(0); - - - } - - public static void changeStatus(final VMStatus status_changed) { - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if (status_changed == VMStatus.Running) { - - vmStarted = true; - } else if (status_changed == VMStatus.Ready || status_changed == VMStatus.Stopped) { - - } else if (status_changed == VMStatus.Saving) { - - } else if (status_changed == VMStatus.Paused) { - - } - } - }); - - } - - public static void install(boolean force) { - progDialog = ProgressDialog.show(activity, "Please Wait", "Installing BIOS...", true); - installerTaskTask = new InstallerTask(); - installerTaskTask.force = force; - installerTaskTask.execute(); - } - - public static void checkAndLoadLibs() { - if (Config.loadNativeLibsEarly) - if (Config.loadNativeLibsMainThread) - setupNativeLibs(); - else - setupNativeLibsAsync(); - } - - public static void clearNotifications() { - NotificationManager notificationManager = (NotificationManager) activity.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancelAll(); - } - - public static void setupNativeLibsAsync() { - - Thread thread = new Thread(new Runnable() { - public void run() { - setupNativeLibs(); - } - }); - thread.setPriority(Thread.MIN_PRIORITY); - thread.start(); - - } - - public static void savePendingEditText() { - View currentView = activity.getCurrentFocus(); - if (currentView != null && currentView instanceof EditText) { - ((EditText) currentView).setFocusable(false); - } - } - - public static void checkLog() { - - Thread t = new Thread(new Runnable() { - public void run() { - - if (MainSettingsManager.getExitCode(activity) != 1) { - MainSettingsManager.setExitCode(activity, 1); - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - UIUtils.promptShowLog(activity); - } - }); - } - } - }); - t.start(); - } - - public static void setupFolders() { - Thread t = new Thread(new Runnable() { - public void run() { - - Config.cacheDir = activity.getCacheDir().getAbsolutePath(); - Config.storagedir = Environment.getExternalStorageDirectory().toString(); - - // Create Temp folder - File folder = new File(Config.getTmpFolder()); - if (!folder.exists()) - folder.mkdirs(); - - - } - }); - t.start(); - } - - //XXX: sometimes this needs to be called from the main thread otherwise - // qemu crashes when it is started later - public static void setupNativeLibs() { - - if (libLoaded) - return; - - //Some devices need stl loaded upfront - //System.loadLibrary("stlport_shared"); - - //Compatibility lib - System.loadLibrary("compat-vectras"); - - //Glib deps - System.loadLibrary("compat-musl"); - - - //Glib - System.loadLibrary("glib-2.0"); - - //Pixman for qemu - System.loadLibrary("pixman-1"); - - //Spice server - if (Config.enable_SPICE) { - System.loadLibrary("crypto"); - System.loadLibrary("ssl"); - System.loadLibrary("spice"); - } - - // //Load SDL library - if (Config.enable_SDL) { - System.loadLibrary("SDL2"); - } - - System.loadLibrary("compat-SDL2-ext"); - - //Vectras needed for vmexecutor - System.loadLibrary("vectras"); - - loadQEMULib(); - - libLoaded = true; - } - - public static void loadQEMULib() { - - try { - System.loadLibrary("qemu-system-i386"); - } catch (Error ex) { - System.loadLibrary("qemu-system-x86_64"); - } - - } - - - public static void setupStrictMode() { - - if (Config.debugStrictMode) { - StrictMode.setThreadPolicy( - new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork() - //.penaltyDeath() - .penaltyLog().build()); - StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects() - .detectLeakedClosableObjects().penaltyLog() - // .penaltyDeath() - .build()); - } - - } - - public static void onLicense() { - PackageInfo pInfo = null; - - try { - pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(), PackageManager.GET_META_DATA); - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return; - } - - final PackageInfo finalPInfo = pInfo; - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - - } - }); - - } - - // Main event function - // Retrives values from saved preferences - public static void onStartButton() { - if (MainService.isRunning) { - startvnc(); - } else { - if (vmexecutor == null) { - - try { - vmexecutor = new StartVM(activity); - } catch (Exception ex) { - UIUtils.toastLong(activity, "Error: " + ex); - return; - - } - } - // dns - vmexecutor.dns_addr = Config.defaultDNSServer; - - vmexecutor.paused = 0; - - if (!vmStarted) { - UIUtils.toastShort(activity, "Starting VM"); - //XXX: make sure that bios files are installed in case we ran out of space in the last - // run - FileInstaller.installFiles(activity, false); - } else { - UIUtils.toastShort(activity, "Connecting to VM"); - } - - if (Config.ui.equals("VNC")) { - vmexecutor.enableqmp = 1; // We enable qemu monitor - startVNC(); - - } else if (Config.ui.equals("SDL")) { - vmexecutor.enableqmp = 0; // We disable qemu monitor - startSDL(); - } else { - vmexecutor.enableqmp = 1; // We enable qemu monitor - startSPICE(); - } - } - } - - public static String getLanguageCode(int index) { - // TODO: Add more languages from /assets/roms/keymaps - switch (index) { - case 0: - return "en-us"; - case 1: - return "es"; - case 2: - return "fr"; - } - return null; - } - - public static void startSDL() { - - Thread tsdl = new Thread(new Runnable() { - public void run() { - startsdl(); - } - }); - if (Config.maxPriority) - tsdl.setPriority(Thread.MAX_PRIORITY); - tsdl.start(); - } - - public static void startVNC() { - - VncCanvas.retries = 0; - if (!vmStarted) { - - Thread tvm = new Thread(new Runnable() { - public void run() { - startvm(activity, Config.UI_VNC); - } - }); - if (Config.maxPriority) - tvm.setPriority(Thread.MAX_PRIORITY); - tvm.start(); - } else { - startvnc(); - } - - - } - - public static void startSPICE() { - - if (!vmStarted) { - - Thread tvm = new Thread(new Runnable() { - public void run() { - startvm(activity, Config.UI_SPICE); - } - }); - if (Config.maxPriority) - tvm.setPriority(Thread.MAX_PRIORITY); - tvm.start(); - } - - } - - public static void onStopButton(boolean exit) { - stopVM(exit); - } - - public static void onRestartButton() { - - execTimer(); - - Machine.resetVM(activity); - } - - public static void onResumeButton() { - - // TODO: This probably has no effect - Thread t = new Thread(new Runnable() { - public void run() { - resumevm(); - } - }); - t.start(); - } - - public static void toggleVisibility(View view) { - if (view.getVisibility() == View.VISIBLE) { - view.setVisibility(View.GONE); - } else if (view.getVisibility() == View.GONE || view.getVisibility() == View.INVISIBLE) { - view.setVisibility(View.VISIBLE); - } - } - - public static boolean onKeyDown(int keyCode, KeyEvent event) { - - if (keyCode == KeyEvent.KEYCODE_BACK) { - activity.moveTaskToBack(true); - return true; // return - } - - return false; - } - - - public static void startvnc() { - - // Wait till Qemu settles - try { - Thread.sleep(2000); - } catch (InterruptedException ex) { - Logger.getLogger(activity.getClass().getName()).log(Level.SEVERE, null, ex); - } - if (MainSettingsManager.getVncExternal(activity)) { - - } else { - connectLocally(); - } - } - - public static void promptConnectLocally(final Activity activity) { - - new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { - @Override - public void run() { - final AlertDialog alertDialog; - alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); - alertDialog.setTitle("VNC Started"); - TextView stateView = new TextView(activity); - stateView.setText("VNC Server started: " + getLocalIpAddress() + ":" + Config.defaultVNCPort + "\n" - + "Warning: VNC Connection is Unencrypted and not secure make sure you're on a private network!\n"); - - stateView.setPadding(20, 20, 20, 20); - alertDialog.setView(stateView); - - alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - alertDialog.dismiss(); - } - }); - alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, "Connect Locally", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - connectLocally(); - } - }); - alertDialog.show(); - } - }, 100); - - - } - - public static void connectLocally() { - //UIUtils.toastShort(MainActivity.this, "Connecting to VM Display"); - Intent intent = getVNCIntent(); - activity.startActivityForResult(intent, Config.VNC_REQUEST_CODE); - } - - public static void startsdl() { - - Intent intent = null; - - intent = new Intent(activity, MainSDLActivity.class); - - android.content.ContentValues values = new android.content.ContentValues(); - activity.startActivityForResult(intent, Config.SDL_REQUEST_CODE); - } - - - public static void resumevm() { - if (vmexecutor != null) { - vmexecutor.resumevm(); - UIUtils.toastShort(activity, "VM Reset"); - } else { - - UIUtils.toastShort(activity, "VM not running"); - } - - } - - public static Intent getVNCIntent() { - return new Intent(activity, com.vectras.qemu.MainVNCActivity.class); - - } - - - public static void goToSettings() { - Intent i = new Intent(activity, MainSettingsManager.class); - activity.startActivity(i); - } - - public static void onViewLog() { - - Thread t = new Thread(new Runnable() { - public void run() { - FileUtils.viewVectrasLog(activity); - } - }); - t.start(); - } - - public static void goToURL(String url) { - - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - activity.startActivity(i); - - } - - public static void stopVM(boolean exit) { - execTimer(); - Machine.stopVM(activity); - } - - public static void stopTimeListener() { - - synchronized (lockTime) { - timeQuit = true; - lockTime.notifyAll(); - } - } - - - public static void timer() { - //XXX: No timers just ping a few times - for (int i = 0; i < 3; i++) { - checkAndUpdateStatus(false); - - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - - } - - public static void checkAndUpdateStatus(boolean force) { - if (vmexecutor != null) { - VMStatus status = checkStatus(); - if (force || status != currStatus) { - currStatus = status; - changeStatus(status); - } - } - } - - public static void execTimer() { - - Thread t = new Thread(new Runnable() { - public void run() { - startTimer(); - } - }); - t.start(); - } - - public static void startTimer() { - stopTimeListener(); - - timeQuit = false; - try { - timer(); - } catch (Exception ex) { - ex.printStackTrace(); - - } - - } - - - public static enum VMStatus { - Ready, Stopped, Saving, Paused, Completed, Failed, Unknown, Running - } - - public static VMStatus checkStatus() { - VMStatus state = VMStatus.Ready; - if (vmexecutor != null && libLoaded && vmexecutor.get_state().toUpperCase().equals("RUNNING")) { - state = VMStatus.Running; - } - return state; - } - - public static class InstallerTask extends AsyncTask { - public boolean force; - - @Override - protected Void doInBackground(Void... arg0) { - onInstall(force); - if (progDialog.isShowing()) { - progDialog.dismiss(); - } - return null; - } - - @Override - protected void onPostExecute(Void test) { - - } - } - -} diff --git a/app/src/main/java/com/vectras/qemu/MainSDLActivity.java b/app/src/main/java/com/vectras/qemu/MainSDLActivity.java index 1a25ff9..48962d4 100644 --- a/app/src/main/java/com/vectras/qemu/MainSDLActivity.java +++ b/app/src/main/java/com/vectras/qemu/MainSDLActivity.java @@ -36,6 +36,7 @@ import com.vectras.qemu.utils.FileUtils; import com.vectras.qemu.utils.Machine; import com.vectras.qemu.utils.QmpClient; +import com.vectras.vm.MainActivity; import com.vectras.vm.R; import com.vectras.vm.utils.UIUtils; @@ -146,13 +147,13 @@ public void run() { } catch (InterruptedException ex) { // Log.v("singletap", "Could not sleep"); } - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1,0, 0); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1,0, 0); try { Thread.sleep(50); } catch (InterruptedException ex) { // Log.v("singletap", "Could not sleep"); } - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1, 0, 0); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1, 0, 0); } }); t.start(); @@ -207,7 +208,7 @@ public void onDestroy() { } this.stopTimeListener(); - MainActivityCommon.vmexecutor.doStopVM(0); + MainActivity.vmexecutor.doStopVM(0); super.onDestroy(); } @@ -370,7 +371,7 @@ private void setUIModeMobile(boolean fitToScreen){ //MainSDLActivity.singleClick(a, 0); Config.mouseMode = Config.MouseMode.Trackpad; MainSettingsManager.setDesktopMode(this, false); - MainActivityCommon.vmexecutor.setRelativeMouseMode(1); + MainActivity.vmexecutor.setRelativeMouseMode(1); if(Config.showToast) UIUtils.toastShort(this.getApplicationContext(), "Trackpad Enabled"); if(fitToScreen) @@ -448,7 +449,7 @@ private void setUIModeDesktop() { Config.mouseMode = Config.MouseMode.External; MainSettingsManager.setDesktopMode(this, true); - MainActivityCommon.vmexecutor.setRelativeMouseMode(0); + MainActivity.vmexecutor.setRelativeMouseMode(0); if(Config.showToast) UIUtils.toastShort(MainSDLActivity.this, "External Mouse Enabled"); onNormalScreen(); @@ -903,17 +904,17 @@ private void onPauseVM() { Thread t = new Thread(new Runnable() { public void run() { // Delete any previous state file - if (MainActivityCommon.vmexecutor.save_state_name != null) { - File file = new File(MainActivityCommon.vmexecutor.save_state_name); + if (MainActivity.vmexecutor.save_state_name != null) { + File file = new File(MainActivity.vmexecutor.save_state_name); if (file.exists()) { file.delete(); } } if(Config.showToast) UIUtils.toastShort(getApplicationContext(), "Please wait while saving VM State"); - MainActivityCommon.vmexecutor.current_fd = MainActivityCommon.vmexecutor.get_fd(MainActivityCommon.vmexecutor.save_state_name); + MainActivity.vmexecutor.current_fd = MainActivity.vmexecutor.get_fd(MainActivity.vmexecutor.save_state_name); - String uri = "fd:" + MainActivityCommon.vmexecutor.current_fd; + String uri = "fd:" + MainActivity.vmexecutor.current_fd; String command = QmpClient.stop(); String msg = QmpClient.sendCommand(command); command = QmpClient.migrate(false, false, uri); @@ -995,19 +996,19 @@ public boolean onTouchEvent(MotionEvent event) { } private void resumeVM() { - if(MainActivityCommon.vmexecutor == null){ + if(MainActivity.vmexecutor == null){ return; } Thread t = new Thread(new Runnable() { public void run() { - if (MainActivityCommon.vmexecutor.paused == 1) { + if (MainActivity.vmexecutor.paused == 1) { try { Thread.sleep(4000); } catch (InterruptedException ex) { Logger.getLogger(MainVNCActivity.class.getName()).log(Level.SEVERE, null, ex); } - MainActivityCommon.vmexecutor.paused = 0; + MainActivity.vmexecutor.paused = 0; String command = QmpClient.cont(); String msg = QmpClient.sendCommand(command); @@ -1123,7 +1124,7 @@ public void onStopTrackingTouch(SeekBar arg0) { int progress = arg0.getProgress()+1; int refreshMs = 1000 / progress; Log.v(TAG, "Changing idle refresh rate: (ms)" + refreshMs); - MainActivityCommon.vmexecutor.setsdlrefreshrate(refreshMs); + MainActivity.vmexecutor.setsdlrefreshrate(refreshMs); } }); @@ -1135,7 +1136,7 @@ public void onStopTrackingTouch(SeekBar arg0) { } public int getCurrentSDLRefreshRate() { - return 1000 / MainActivityCommon.vmexecutor.getsdlrefreshrate(); + return 1000 / MainActivity.vmexecutor.getsdlrefreshrate(); } @@ -1194,7 +1195,7 @@ public void onClick(DialogInterface dialog, int i) { protected synchronized void runSDLMain(){ //We go through the vm executor - MainActivityCommon.startvm(this, Config.UI_SDL); + MainActivity.startvm(this, Config.UI_SDL); //XXX: we hold the thread because SDLActivity will exit try { @@ -1481,11 +1482,11 @@ else if(event.getButtonState() == MotionEvent.BUTTON_TERTIARY) if (action == MotionEvent.ACTION_MOVE) { if(Config.mouseMode == Config.MouseMode.External) { //Log.d("SDL", "onTouch Absolute Move by=" + action + ", X,Y=" + (x) + "," + (y) + " P=" + p); - MainActivityCommon.vmexecutor.onVectrasMouse(0, MotionEvent.ACTION_MOVE,0, x , y ); + MainActivity.vmexecutor.onVectrasMouse(0, MotionEvent.ACTION_MOVE,0, x , y ); }else { //Log.d("SDL", "onTouch Relative Moving by=" + action + ", X,Y=" + (x - // old_x) + "," + (y - old_y) + " P=" + p); - MainActivityCommon.vmexecutor.onVectrasMouse(0, MotionEvent.ACTION_MOVE,1, (x - old_x) * sensitivity_mult, (y - old_y) * sensitivity_mult); + MainActivity.vmexecutor.onVectrasMouse(0, MotionEvent.ACTION_MOVE,1, (x - old_x) * sensitivity_mult, (y - old_y) * sensitivity_mult); } } @@ -1501,9 +1502,9 @@ else if (event.getAction() == event.ACTION_UP ) { if(sdlMouseButton == Config.SDL_MOUSE_MIDDLE ||sdlMouseButton == Config.SDL_MOUSE_RIGHT ) { - MainActivityCommon.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_UP, relative, x, y); + MainActivity.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_UP, relative, x, y); } else if (sdlMouseButton != 0) { - MainActivityCommon.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_UP, relative, x, y); + MainActivity.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_UP, relative, x, y); } else { // if we don't have inforamtion about which button we can make some guesses //Or only the last one pressed @@ -1511,17 +1512,17 @@ else if (event.getAction() == event.ACTION_UP ) { if(lastMouseButtonDown == Config.SDL_MOUSE_MIDDLE ||lastMouseButtonDown == Config.SDL_MOUSE_RIGHT ) { - MainActivityCommon.vmexecutor.onVectrasMouse(lastMouseButtonDown, MotionEvent.ACTION_UP, relative,x, y); + MainActivity.vmexecutor.onVectrasMouse(lastMouseButtonDown, MotionEvent.ACTION_UP, relative,x, y); }else - MainActivityCommon.vmexecutor.onVectrasMouse(lastMouseButtonDown, MotionEvent.ACTION_UP, relative, x, y); + MainActivity.vmexecutor.onVectrasMouse(lastMouseButtonDown, MotionEvent.ACTION_UP, relative, x, y); } else { //ALl buttons if (Config.mouseMode == Config.MouseMode.Trackpad) { - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1, 0, 0); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1, 0, 0); } else if (Config.mouseMode == Config.MouseMode.External) { - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 0, x, y); - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_UP, 0, x, y); - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_UP, 0, x, y); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 0, x, y); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_UP, 0, x, y); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_UP, 0, x, y); } } } @@ -1537,7 +1538,7 @@ else if (event.getAction() == event.ACTION_DOWN sdlMouseButton = Config.SDL_MOUSE_LEFT; } - MainActivityCommon.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_DOWN, relative, x, y); + MainActivity.vmexecutor.onVectrasMouse(sdlMouseButton, MotionEvent.ACTION_DOWN, relative, x, y); lastMouseButtonDown = sdlMouseButton; } return true; @@ -1613,13 +1614,13 @@ public boolean rightClick(final MotionEvent e, final int i) { Thread t = new Thread(new Runnable() { public void run() { Log.d("SDL", "Mouse Right Click"); - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_DOWN, 1, -1, -1); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_DOWN, 1, -1, -1); try { Thread.sleep(100); } catch (InterruptedException ex) { // Log.v("SDLSurface", "Interrupted: " + ex); } - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_UP, 1, -1, -1); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_RIGHT, MotionEvent.ACTION_UP, 1, -1, -1); } }); t.start(); @@ -1631,13 +1632,13 @@ public boolean middleClick(final MotionEvent e, final int i) { Thread t = new Thread(new Runnable() { public void run() { Log.d("SDL", "Mouse Middle Click"); - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_DOWN, 1,-1, -1); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_DOWN, 1,-1, -1); try { Thread.sleep(100); } catch (InterruptedException ex) { // Log.v("SDLSurface", "Interrupted: " + ex); } - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_UP, 1,-1, -1); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_MIDDLE, MotionEvent.ACTION_UP, 1,-1, -1); } }); t.start(); @@ -1651,13 +1652,13 @@ private void doubleClick(final MotionEvent event, final int pointer_id) { public void run() { //Log.d("SDL", "Mouse Double Click"); for (int i = 0; i < 2; i++) { - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1, 0, 0); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1, 0, 0); try { Thread.sleep(50); } catch (InterruptedException ex) { // Log.v("doubletap", "Could not sleep"); } - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1,0, 0); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_UP, 1,0, 0); try { Thread.sleep(50); } catch (InterruptedException ex) { @@ -1748,7 +1749,7 @@ public boolean onDoubleTap(MotionEvent event) { private void dragPointer(MotionEvent event) { - MainActivityCommon.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1, 0, 0); + MainActivity.vmexecutor.onVectrasMouse(Config.SDL_MOUSE_LEFT, MotionEvent.ACTION_DOWN, 1, 0, 0); Vibrator v = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE); if (v.hasVibrator()) { v.vibrate(100); @@ -1804,7 +1805,7 @@ public boolean onGenericMotion(View v, MotionEvent event) { x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0); y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0); // Log.d("SDL", "Mouse Scroll: " + x + "," + y); - MainActivityCommon.vmexecutor.onVectrasMouse(0, action, 0, x, y); + MainActivity.vmexecutor.onVectrasMouse(0, action, 0, x, y); return true; case MotionEvent.ACTION_HOVER_MOVE: @@ -1845,7 +1846,7 @@ private void processHoverMouse(float x,float y,float p, int action) { if(Config.mouseMode == Config.MouseMode.External) { //Log.d("SDL", "Mouse Hover: " + x + "," + y); - MainActivityCommon.vmexecutor.onVectrasMouse(0, action, 0, x, y); + MainActivity.vmexecutor.onVectrasMouse(0, action, 0, x, y); } } diff --git a/app/src/main/java/com/vectras/qemu/MainService.java b/app/src/main/java/com/vectras/qemu/MainService.java index 85c7fa3..5234180 100644 --- a/app/src/main/java/com/vectras/qemu/MainService.java +++ b/app/src/main/java/com/vectras/qemu/MainService.java @@ -82,7 +82,7 @@ public void run() { @Override public void run() { - MainActivityCommon.startvnc(); + MainActivity.startvnc(); } }, 2000); } @@ -91,7 +91,7 @@ public void run() { String res = executor.startvm(); //VM has exited - MainActivityCommon.cleanup(); + MainActivity.cleanup(); } }); @@ -114,7 +114,7 @@ public void run() { } catch (InterruptedException e) { e.printStackTrace(); } - MainActivityCommon.startTimer(); + MainActivity.startTimer(); } }); t.start(); @@ -123,11 +123,11 @@ public void run() { private void setUpAsForeground(String text) { isRunning = true; - MainActivityCommon.vmStarted = true; + MainActivity.vmStarted = true; Class clientClass = null; if (Config.ui != null) { if (Config.ui.equals("VNC")) { - if (MainSettingsManager.getVncExternal(MainActivityCommon.activity)) { + if (MainSettingsManager.getVncExternal(MainActivity.activity)) { MainActivity.extVncLayout.setVisibility(View.VISIBLE); MainActivity.appbar.setExpanded(true); } diff --git a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java index 72db3dc..e97ed18 100644 --- a/app/src/main/java/com/vectras/qemu/MainSettingsManager.java +++ b/app/src/main/java/com/vectras/qemu/MainSettingsManager.java @@ -19,13 +19,17 @@ package com.vectras.qemu; import android.app.Activity; +import android.app.AlarmManager; +import android.app.PendingIntent; import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Environment; +import android.os.Handler; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; import android.view.MenuItem; @@ -34,197 +38,257 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceFragment; import androidx.preference.PreferenceFragmentCompat; + import com.vectras.vm.R; +import com.vectras.vm.SplashActivity; import java.util.List; -public class MainSettingsManager extends AppCompatActivity { - - private static final String TAG = "SettingsActivity"; +public class MainSettingsManager extends AppCompatActivity + implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { public static MainSettingsManager activity; + + private static Handler mHandler; public static SharedPreferences sp; - public static int fragment = 0; @Override protected void onCreate(Bundle savedInstanceState) { + // TODO: Implement this method super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); + activity = this; - fragment = 0; + sp = PreferenceManager.getDefaultSharedPreferences(activity); - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - setSupportActionBar(toolbar); + PreferenceFragmentCompat preference = new MainPreferencesFragment(); + Intent intent = getIntent(); + + // add preference settings + getSupportFragmentManager().beginTransaction() + .replace(R.id.settingz, preference) + .commit(); + + // toolbar + Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setDisplayShowHomeEnabled(true); - toolbar.setTitle("Settings"); } + @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if(item.getItemId()== android.R.id.home){ - if (fragment == 0) { - finish(); - } else { - MainFragment.mainFragment(); - } - } - return super.onOptionsItemSelected(item); + public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) { + // Instantiate the new Fragment + final Bundle bundle = pref.getExtras(); + final Fragment fragment = Fragment.instantiate(this, pref.getFragment(), bundle); + + fragment.setTargetFragment(caller, 0); + + // Replace the existing Fragment with the new Fragment + getSupportFragmentManager().beginTransaction() + .replace(R.id.settingz, fragment) + .addToBackStack(null) + .commit(); + + return true; } - public static class MainFragment extends PreferenceFragmentCompat { + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } - public static MainFragment fr; + public static class MainPreferencesFragment extends PreferenceFragmentCompat + implements Preference.OnPreferenceChangeListener { @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { - setPreferencesFromResource(R.xml.headers_preference, rootKey); - fr = MainFragment.this; - fragment = 0; - findPreference("app").setOnPreferenceClickListener(preference -> { - getFragmentManager().beginTransaction().replace(R.id.settingz, - new AppPreferencesFragment()).commit(); - return false; - }); - findPreference("userinterface").setOnPreferenceClickListener(preference -> { - getFragmentManager().beginTransaction().replace(R.id.settingz, - new UserInterfacePreferencesFragment()).commit(); - return false; - }); - findPreference("qemu").setOnPreferenceClickListener(preference -> { - getFragmentManager().beginTransaction().replace(R.id.settingz, - new QemuPreferencesFragment()).commit(); - return false; - }); - findPreference("vnc").setOnPreferenceClickListener(preference -> { - getFragmentManager().beginTransaction().replace(R.id.settingz, - new VncPreferencesFragment()).commit(); - return false; - }); - } - public static void mainFragment(){ - fr.getFragmentManager().beginTransaction().replace(R.id.settingz, - new MainFragment()).commit(); + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } @Override public void onResume() { super.onResume(); - fragment = 0; + } @Override public void onPause() { super.onPause(); - fragment = 0; + + } + + + @Override + public void onCreatePreferences(Bundle bundle, String root_key) { + // Load the Preferences from the XML file + setPreferencesFromResource(R.xml.headers_preference, root_key); + + } + + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + if (pref.getKey().equals("app")) { + + } + return true; } } + public static class AppPreferencesFragment extends PreferenceFragmentCompat - implements OnSharedPreferenceChangeListener { + implements Preference.OnPreferenceChangeListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - sp = getPreferenceScreen().getSharedPreferences(); - - Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); - activity.setSupportActionBar(toolbar); - activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); - activity.getSupportActionBar().setDisplayShowHomeEnabled(true); - toolbar.setTitle("APP SETTINGS"); - fragment = 1; - } - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.settings, rootKey); } @Override public void onResume() { super.onResume(); - fragment = 1; + } @Override public void onPause() { super.onPause(); + } - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - sp = sharedPreferences; + + @Override + public void onCreatePreferences(Bundle bundle, String root_key) { + // Load the Preferences from the XML file + setPreferencesFromResource(R.xml.settings, root_key); + } + + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + if (pref.getKey().equals("app")) { + + } + return true; + } + } public static class UserInterfacePreferencesFragment extends PreferenceFragmentCompat - implements OnSharedPreferenceChangeListener { + implements Preference.OnPreferenceChangeListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.userinterface); - sp = getPreferenceScreen().getSharedPreferences(); - - Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); - activity.setSupportActionBar(toolbar); - activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); - activity.getSupportActionBar().setDisplayShowHomeEnabled(true); - toolbar.setTitle("USER INTERFACE"); - fragment = 2; + + mHandler = new Handler(); + Preference pref = findPreference("modeNight"); + if (pref != null) { + pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + + @Override + public boolean onPreferenceChange(@NonNull Preference preference, + Object newValue) { + onNightMode(); + return true; + } + + }); + } } - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { + private void onNightMode() { + 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); } @Override public void onResume() { super.onResume(); - fragment = 2; + } @Override public void onPause() { super.onPause(); + + } + + + @Override + public void onCreatePreferences(Bundle bundle, String root_key) { + // Load the Preferences from the XML file + setPreferencesFromResource(R.xml.userinterface, root_key); + } - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - sp = sharedPreferences; + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + return true; } } + public static class QemuPreferencesFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.qemu); - sp = getPreferenceScreen().getSharedPreferences(); - - Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); - activity.setSupportActionBar(toolbar); - activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); - activity.getSupportActionBar().setDisplayShowHomeEnabled(true); - toolbar.setTitle("QEMU"); - fragment = 3; + Preference pref = findPreference("customMemory"); + if (pref != null) { + pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + + @Override + public boolean onPreferenceChange(@NonNull Preference preference, + Object newValue) { + findPreference("memory").setEnabled(!sp.getBoolean("customMemory", false)); + return true; + } + + }); + } + Preference pref2 = findPreference("customMemory"); + if (pref2 != null) { + pref2.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + + @Override + public boolean onPreferenceChange(@NonNull Preference preference, + Object newValue) { + if (MainSettingsManager.getVirtio(activity)) { + Config.hd_if_type = "virtio"; + } else { + Config.hd_if_type = "ide"; + } + return true; + } + + }); + } } - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { - + private void onMemory() { + findPreference("memory").setEnabled(sp.getBoolean("customMemory", false)); } @Override public void onResume() { super.onResume(); onMemory(); - fragment = 3; - } - - private void onMemory() { - //findPreference("memory").setEnabled(getCusRam(activity)); } @Override @@ -233,49 +297,60 @@ public void onPause() { onMemory(); } + @Override - public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { - onMemory(); + public void onCreatePreferences(Bundle bundle, String root_key) { + // Load the Preferences from the XML file + setPreferencesFromResource(R.xml.qemu, root_key); + + } + + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + return true; } + } + public static class VncPreferencesFragment extends PreferenceFragmentCompat - implements OnSharedPreferenceChangeListener { + implements Preference.OnPreferenceChangeListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.vnc); - sp = getPreferenceScreen().getSharedPreferences(); - - Toolbar toolbar = (Toolbar) activity.findViewById(R.id.toolbar); - activity.setSupportActionBar(toolbar); - activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); - activity.getSupportActionBar().setDisplayShowHomeEnabled(true); - toolbar.setTitle("VNC"); - fragment = 4; - } - - @Override - public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) { } @Override public void onResume() { super.onResume(); - fragment = 4; + } @Override public void onPause() { super.onPause(); + } - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - sp = sharedPreferences; + + @Override + public void onCreatePreferences(Bundle bundle, String root_key) { + // Load the Preferences from the XML file + setPreferencesFromResource(R.xml.vnc, root_key); + + } + + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + if (pref.getKey().equals("app")) { + + } + return true; } } + static String getDNSServer(Activity activity) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); return prefs.getString("dnsServer", Config.defaultDNSServer); @@ -543,6 +618,17 @@ public static boolean getCusRam(Activity activity) { return prefs.getBoolean("customMemory", false); } + public static void setVirtio(Activity activity, Boolean virtio) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("virtio", virtio); + edit.apply(); + } + + public static boolean getVirtio(Activity activity) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + return prefs.getBoolean("virtio", false); + } public static boolean isFirstLaunch(Activity activity) { PackageInfo pInfo = null; @@ -572,14 +658,4 @@ public static void setFirstLaunch(Activity activity) { edit.commit(); } - @Override - public void onBackPressed() { - if (fragment == 0) { - finish(); - super.onBackPressed(); - } else { - MainFragment.mainFragment(); - } - } - } diff --git a/app/src/main/java/com/vectras/qemu/MainVNCActivity.java b/app/src/main/java/com/vectras/qemu/MainVNCActivity.java index 5ad8e27..c2a9a9e 100644 --- a/app/src/main/java/com/vectras/qemu/MainVNCActivity.java +++ b/app/src/main/java/com/vectras/qemu/MainVNCActivity.java @@ -52,6 +52,7 @@ import android.widget.TextView; import com.vectras.vm.Fragment.ControlersOptionsFragment; +import com.vectras.vm.MainActivity; import com.vectras.vm.R; import com.vectras.qemu.utils.Machine; import com.vectras.qemu.utils.QmpClient; @@ -506,11 +507,11 @@ public void onResume() { public void checkStatus() { while (timeQuit != true) { - MainActivityCommon.VMStatus status = Machine.checkSaveVMStatus(activity); + MainActivity.VMStatus status = Machine.checkSaveVMStatus(activity); Log.v(TAG, "Status: " + status); - if (status == MainActivityCommon.VMStatus.Unknown - || status == MainActivityCommon.VMStatus.Completed - || status == MainActivityCommon.VMStatus.Failed + if (status == MainActivity.VMStatus.Unknown + || status == MainActivity.VMStatus.Completed + || status == MainActivity.VMStatus.Failed ) { //Log.v(TAG, "Saving state is done: " + status); stopTimeListener(); @@ -1037,12 +1038,12 @@ public boolean dispatchKeyEvent(KeyEvent event) { } private void resumeVM() { - if (MainActivityCommon.vmexecutor == null) { + if (MainActivity.vmexecutor == null) { return; } Thread t = new Thread(new Runnable() { public void run() { - if (MainActivityCommon.vmexecutor.paused == 1) { + if (MainActivity.vmexecutor.paused == 1) { try { Thread.sleep(4000); } catch (InterruptedException ex) { @@ -1051,7 +1052,7 @@ public void run() { if (vncCanvas == null) return; - MainActivityCommon.vmexecutor.paused = 0; + MainActivity.vmexecutor.paused = 0; String command = QmpClient.cont(); String msg = QmpClient.sendCommand(command); new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @@ -1072,8 +1073,8 @@ private void onPauseVM() { Thread t = new Thread(new Runnable() { public void run() { // Delete any previous state file - if (MainActivityCommon.vmexecutor.save_state_name != null) { - File file = new File(MainActivityCommon.vmexecutor.save_state_name); + if (MainActivity.vmexecutor.save_state_name != null) { + File file = new File(MainActivity.vmexecutor.save_state_name); if (file.exists()) { file.delete(); } @@ -1081,7 +1082,7 @@ public void run() { UIUtils.toastShort(getApplicationContext(), "Please wait while saving VM State"); - String uri = "fd:" + MainActivityCommon.vmexecutor.get_fd(MainActivityCommon.vmexecutor.save_state_name); + String uri = "fd:" + MainActivity.vmexecutor.get_fd(MainActivity.vmexecutor.save_state_name); String command = QmpClient.stop(); String msg = QmpClient.sendCommand(command); // if (msg != null) @@ -1312,7 +1313,7 @@ public void onStopTrackingTouch(SeekBar arg0) { int progress = arg0.getProgress() + 1; int refreshMs = 1000 / progress; Log.v(TAG, "Changing display refresh rate (ms): " + refreshMs); - MainActivityCommon.vmexecutor.setvncrefreshrate(refreshMs); + MainActivity.vmexecutor.setvncrefreshrate(refreshMs); } }); @@ -1325,7 +1326,7 @@ public void onStopTrackingTouch(SeekBar arg0) { } public int getCurrentVNCRefreshRate() { - return 1000 / MainActivityCommon.vmexecutor.getvncrefreshrate(); + return 1000 / MainActivity.vmexecutor.getvncrefreshrate(); } } diff --git a/app/src/main/java/com/vectras/qemu/jni/StartVM.java b/app/src/main/java/com/vectras/qemu/jni/StartVM.java index af63609..f819182 100644 --- a/app/src/main/java/com/vectras/qemu/jni/StartVM.java +++ b/app/src/main/java/com/vectras/qemu/jni/StartVM.java @@ -7,7 +7,6 @@ import android.view.MotionEvent; import com.vectras.qemu.Config; -import com.vectras.qemu.MainActivityCommon; import com.vectras.qemu.MainSDLActivity; import com.vectras.qemu.MainService; import com.vectras.qemu.MainSettingsManager; @@ -15,6 +14,7 @@ import com.vectras.qemu.utils.Machine; import com.vectras.qemu.utils.QmpClient; import com.vectras.qemu.utils.RamInfo; +import com.vectras.vm.MainActivity; import com.vectras.vm.logger.VectrasStatus; import com.vectras.vm.utils.UIUtils; @@ -126,8 +126,8 @@ public StartVM(Context context) throws Exception { this.context = context; this.libqemu = FileUtils.getNativeLibDir(context) + "/libqemu-system-x86_64.so"; this.arch = "x86_64"; - this.cpuNum = MainSettingsManager.getCpuNum(MainActivityCommon.activity); - if (MainSettingsManager.getMTTCG(MainActivityCommon.activity)) + this.cpuNum = MainSettingsManager.getCpuNum(MainActivity.activity); + if (MainSettingsManager.getMTTCG(MainActivity.activity)) this.enable_mttcg = 1; else this.enable_mttcg = 0; @@ -384,7 +384,7 @@ private void addCpuBoardOptions(ArrayList paramsList) { if (this.cpuNum > 1 && (enablekvm == 1 || enable_mttcg == 1 || !Config.enableSMPOnlyOnKVM)) { paramsList.add("-smp"); - paramsList.add(this.cpuNum + ""); + paramsList.add("sockets="+"1"+",cores="+this.cpuNum+",threads="+this.cpuNum+""); } if (machine_type != null && !machine_type.equals("Default")) { @@ -411,7 +411,7 @@ else if (arch.equals("x86_64")) if (this.cpu != null && !cpu.equals("Default")) { paramsList.add("-cpu"); - paramsList.add(cpu); + paramsList.add(cpu + ",+avx"); } @@ -427,6 +427,9 @@ else if (arch.equals("x86_64")) String tcgParams = "tcg"; if (cpuNum > 1) tcgParams += ",thread=multi"; + else + tcgParams += ",thread=single"; + tcgParams += ",tb-size=2048"; paramsList.add(tcgParams); //#endif } diff --git a/app/src/main/java/com/vectras/qemu/utils/Machine.java b/app/src/main/java/com/vectras/qemu/utils/Machine.java index b9079d3..85716c2 100644 --- a/app/src/main/java/com/vectras/qemu/utils/Machine.java +++ b/app/src/main/java/com/vectras/qemu/utils/Machine.java @@ -9,7 +9,7 @@ import android.os.Looper; import android.util.Log; import com.vectras.qemu.Config; -import com.vectras.qemu.MainActivityCommon; +import com.vectras.vm.MainActivity; import com.vectras.vm.R; import com.vectras.vm.utils.UIUtils; @@ -34,8 +34,8 @@ public void onClick(DialogInterface dialog, int which) { activity.finish(); } - if (MainActivityCommon.vmexecutor != null) { - MainActivityCommon.vmexecutor.stopvm(0); + if (MainActivity.vmexecutor != null) { + MainActivity.vmexecutor.stopvm(0); } } }).show(); @@ -45,11 +45,11 @@ public void onClick(DialogInterface dialog, int which) { public static void onRestartVM(final Context context) { Thread t = new Thread(new Runnable() { public void run() { - if (MainActivityCommon.vmexecutor != null) { + if (MainActivity.vmexecutor != null) { Log.v(TAG, "Restarting the VM..."); - MainActivityCommon.vmexecutor.stopvm(1); + MainActivity.vmexecutor.stopvm(1); - MainActivityCommon.vmStarted = true; + MainActivity.vmStarted = true; if(Config.showToast) UIUtils.toastShort(context, "VM Reset"); @@ -94,8 +94,8 @@ public void onClick(DialogInterface dialog, int which) { activity.finish(); } - if (MainActivityCommon.vmexecutor != null) { - MainActivityCommon.vmexecutor.stopvm(0); + if (MainActivity.vmexecutor != null) { + MainActivity.vmexecutor.stopvm(0); } } }).setNegativeButton("No", new DialogInterface.OnClickListener() { @@ -104,9 +104,9 @@ public void onClick(DialogInterface dialog, int which) { }).show(); } - public static MainActivityCommon.VMStatus checkSaveVMStatus(final Activity activity) { + public static MainActivity.VMStatus checkSaveVMStatus(final Activity activity) { String pause_state = ""; - if (MainActivityCommon.vmexecutor != null) { + if (MainActivity.vmexecutor != null) { String command = QmpClient.query_migrate(); String res = QmpClient.sendCommand(command); @@ -130,9 +130,9 @@ public static MainActivityCommon.VMStatus checkSaveVMStatus(final Activity activ } if (pause_state.toUpperCase().equals("ACTIVE")) { - return MainActivityCommon.VMStatus.Saving; + return MainActivity.VMStatus.Saving; } else if (pause_state.toUpperCase().equals("COMPLETED")) { - MainActivityCommon.vmexecutor.paused = 1; + MainActivity.vmexecutor.paused = 1; new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override @@ -140,7 +140,7 @@ public void run() { promptPausedVM(activity); } }, 1000); - return MainActivityCommon.VMStatus.Completed; + return MainActivity.VMStatus.Completed; } else if (pause_state.toUpperCase().equals("FAILED")) { new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @@ -149,9 +149,9 @@ public void run() { pausedErrorVM(activity, null); } }, 100); - return MainActivityCommon.VMStatus.Failed; + return MainActivity.VMStatus.Failed; } - return MainActivityCommon.VMStatus.Unknown; + return MainActivity.VMStatus.Unknown; } public static boolean isHostX86_64() { diff --git a/app/src/main/java/com/vectras/vm/MainActivity.java b/app/src/main/java/com/vectras/vm/MainActivity.java index e1d6f44..fb9d999 100644 --- a/app/src/main/java/com/vectras/vm/MainActivity.java +++ b/app/src/main/java/com/vectras/vm/MainActivity.java @@ -2,29 +2,38 @@ import static android.os.Build.VERSION.SDK_INT; +import android.androidVNC.RfbProto; +import android.androidVNC.VncCanvas; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; import android.app.Activity; 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; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.graphics.Color; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.os.Handler; import android.os.Looper; +import android.os.StrictMode; import android.preference.PreferenceManager; import android.text.Html; import android.util.Log; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.Button; +import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; @@ -40,28 +49,26 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; +import androidx.vectordrawable.graphics.drawable.ArgbEvaluator; import androidx.viewpager.widget.ViewPager; -import com.bumptech.glide.Glide; import com.google.android.gms.ads.LoadAdError; import com.google.android.gms.ads.MobileAds; 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.bottomappbar.BottomAppBar; import com.google.android.material.button.MaterialButton; -import com.google.android.material.color.DynamicColors; -import com.google.android.material.color.utilities.DynamicColor; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; -import com.google.firebase.database.FirebaseDatabase; import com.vectras.qemu.Config; -import com.vectras.qemu.MainActivityCommon; +import com.vectras.qemu.MainSDLActivity; import com.vectras.qemu.MainService; import com.vectras.qemu.MainSettingsManager; import com.vectras.qemu.jni.StartVM; import com.vectras.qemu.utils.FileUtils; +import com.vectras.qemu.utils.Machine; +import com.vectras.qemu.utils.QmpClient; import com.vectras.vm.Fragment.HomeFragment; import com.vectras.vm.Fragment.LoggerFragment; import com.vectras.vm.logger.VectrasStatus; @@ -72,12 +79,13 @@ import com.google.android.gms.ads.AdView; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.bottomnavigation.BottomNavigationView; -import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.navigation.NavigationView; +import com.vectras.vm.utils.UIUtils; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; @@ -85,6 +93,8 @@ import java.util.Objects; import java.util.TimerTask; import java.util.Timer; +import java.util.logging.Level; +import java.util.logging.Logger; public class MainActivity extends AppCompatActivity { @@ -123,24 +133,6 @@ public void onClick(DialogInterface dialog, int which) { ad.show(); } - // This is easier: traverse the interfaces and get the local IPs - public static String getLocalIpAddress() { - try { - for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { - NetworkInterface intf = en.nextElement(); - for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { - InetAddress inetAddress = enumIpAddr.nextElement(); - if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) { - return inetAddress.getHostAddress().toString(); - } - } - } - } catch (SocketException ex) { - ex.printStackTrace(); - } - return null; - } - /** * Called when the activity is first created. */ @@ -148,12 +140,12 @@ public static String getLocalIpAddress() { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - MainActivityCommon.activity = this; - MainActivityCommon.clearNotifications(); - MainActivityCommon.setupFolders(); - MainActivityCommon.setupStrictMode(); - MainActivityCommon.execTimer(); - MainActivityCommon.checkAndLoadLibs(); + activity = this; + clearNotifications(); + setupFolders(); + setupStrictMode(); + execTimer(); + checkAndLoadLibs(); Config.logFilePath = Config.cacheDir + "/vectras/vectras-log.txt"; activity = this; this.setContentView(R.layout.main); @@ -236,7 +228,7 @@ public boolean onOptionsItemSelected(MenuItem item) { appbar.setExpanded(false); } else if (id == R.id.installRoms) { - startActivity(new Intent(MainActivity.activity, RomsManagerActivity.class)); + startActivity(new Intent(activity, RomsManagerActivity.class)); } return super.onOptionsItemSelected(item); @@ -296,7 +288,7 @@ public void setupWidgets() { stopBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - MainActivityCommon.onStopButton(true); + onStopButton(true); } }); viewPager = findViewById(R.id.viewPager); @@ -349,7 +341,12 @@ public void onPageScrollStateChanged(int state) { TextView navEmail = (TextView) headerView.findViewById(R.id.emailTxt); navEmail.setText(email); TextView viewProfile = (TextView) headerView.findViewById(R.id.viewProfile); - + TextView appNameTxt = (TextView) headerView.findViewById(R.id.appNameTxt); + /*ObjectAnimator rgbAnim=ObjectAnimator.ofObject(navUsername,"textColor",new ArgbEvaluator(), Color.RED,Color.GREEN,Color.BLUE); + rgbAnim.setDuration(500); + rgbAnim.setRepeatMode(ValueAnimator.REVERSE); + rgbAnim.setRepeatCount(ValueAnimator.INFINITE); + rgbAnim.start();*/ ImageView ivProfile = (ImageView) headerView.findViewById(R.id.profilePic2); viewProfile.setOnClickListener(new View.OnClickListener() { @@ -473,6 +470,38 @@ public void onInitializationComplete(InitializationStatus initializationStatus) if (photoUrl != null) Glide.with(activity).load(photoUrl.toString()).into(profilePic); }*/ + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + if (!prefs.getBoolean("tgDialog", false)) { + AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("JOIN US ON TELEGRAM"); + alertDialog.setMessage("Join us on Telegram where we publish all the news and updates and receive your opinions and bugs"); + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "JOIN", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + String tg = "https://t.me/vectras_os"; + Intent f = new Intent(Intent.ACTION_VIEW); + f.setData(Uri.parse(tg)); + startActivity(f); + return; + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, "CANCEL", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + return; + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "DONT SHOW AGAIN", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + SharedPreferences.Editor edit = prefs.edit(); + edit.putBoolean("tgDialog", true); + edit.apply(); + return; + } + }); + alertDialog.show(); + } } public static int safeLongToInt(long l) { @@ -492,14 +521,6 @@ public void onBackPressed() { } } - private void goToURL(String url) { - - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse(url)); - activity.startActivity(i); - - } - @Override public void onStop() { super.onStop(); @@ -508,13 +529,18 @@ public void onStop() { @Override public void onDestroy() { super.onDestroy(); - MainActivityCommon.stopTimeListener(); + stopTimeListener(); } @Override public void onStart() { super.onStart(); + if (MainSettingsManager.getVirtio(activity)) { + Config.hd_if_type = "virtio"; + } else { + Config.hd_if_type = "ide"; + } InterstitialAd.load(this, "ca-app-pub-3568137780412047/7745973511", adRequest, new InterstitialAdLoadCallback() { @Override @@ -532,8 +558,8 @@ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { mInterstitialAd = null; } }); - if (mInterstitialAd != null) { - mInterstitialAd.show(MainActivity.this); + if (mInterstitialAd != null && !MainService.isRunning) { + mInterstitialAd.show(this); } else { Log.d("TAG", "The interstitial ad wasn't ready yet."); } @@ -541,53 +567,632 @@ public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { public void onPause() { super.onPause(); - MainActivityCommon.stopTimeListener(); + stopTimeListener(); } public boolean loaded = false; public void onResume() { super.onResume(); - assert mCurrentUser != null; - String name = mCurrentUser.getDisplayName(); - String email = mCurrentUser.getEmail(); - Uri picture = mCurrentUser.getPhotoUrl(); - NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); - View headerView = navigationView.getHeaderView(0); - TextView navUsername = (TextView) headerView.findViewById(R.id.usernameTxt); - navUsername.setText(name); - TextView navEmail = (TextView) headerView.findViewById(R.id.emailTxt); - navEmail.setText(email); - ImageView ivProfile = (ImageView) headerView.findViewById(R.id.profilePic2); if (MainService.isRunning && Objects.equals(Config.ui, "VNC")) { - MainActivityCommon.startvnc(); + startvnc(); } - MainActivityCommon.execTimer(); + execTimer(); + } - InterstitialAd.load(this, "ca-app-pub-3568137780412047/7745973511", adRequest, - new InterstitialAdLoadCallback() { - @Override - public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { - // The mInterstitialAd reference will be null until - // an ad is loaded. - mInterstitialAd = interstitialAd; - Log.i(TAG, "onAdLoaded"); + public static VMStatus currStatus = VMStatus.Ready; + public static boolean vmStarted = false; + public static StartVM vmexecutor; + public static String vnc_passwd = "vectras"; + public static int vnc_allow_external = 1; + public static int qmp_allow_external = 0; + public static ProgressDialog progDialog; + public static View parent; + public static InstallerTask installerTaskTask; + public static boolean timeQuit = false; + public static Object lockTime = new Object(); + + public static boolean libLoaded; + + + static public void onInstall(boolean force) { + FileInstaller.installFiles(activity, force); + } + + public static String getVnc_passwd() { + return vnc_passwd; + } + + public static void setVnc_passwd(String vnc_passwd) { + vnc_passwd = vnc_passwd; + } + + public static String getLocalIpAddress() { + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress() && inetAddress.getHostAddress().toString().contains(".")) { + return inetAddress.getHostAddress().toString(); } + } + } + } catch (SocketException ex) { + ex.printStackTrace(); + } + return null; + } - @Override - public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { - // Handle the error - Log.d(TAG, loadAdError.toString()); - mInterstitialAd = null; + // Start calling the JNI interface + public static void startvm(Activity activity, int UI) { + QmpClient.allow_external = (qmp_allow_external == 1); + vmexecutor.qmp_allow_external = qmp_allow_external; + + if (UI == Config.UI_VNC) { + // disable sound card with VNC + vmexecutor.enablevnc = 1; + vmexecutor.enablespice = 0; + vmexecutor.sound_card = null; + vmexecutor.vnc_allow_external = vnc_allow_external; + RfbProto.allow_external = (vnc_allow_external == 1); + vmexecutor.vnc_passwd = vnc_passwd; + } else if (UI == Config.UI_SDL) { + vmexecutor.enablevnc = 0; + vmexecutor.enablespice = 0; + } else if (UI == Config.UI_SPICE) { + vmexecutor.vnc_allow_external = vnc_allow_external; + vmexecutor.vnc_passwd = vnc_passwd; + vmexecutor.enablevnc = 0; + vmexecutor.enablespice = 1; + } + vmexecutor.startvm(activity, UI); + + } + + + public static void cleanup() { + + vmStarted = false; + + //XXX flush and close all file descriptors if we haven't already + FileUtils.close_fds(); + + ////XXX; we wait till fds flush and close + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + //set the exit code + MainSettingsManager.setExitCode(activity, 1); + + //XXX: SDL seems to lock the keyboard events + // unless we finish the starting activity + activity.finish(); + + Log.v(TAG, "Exit"); + //XXX: We exit here to force unload the native libs + System.exit(0); + + + } + + public static void changeStatus(final VMStatus status_changed) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (status_changed == VMStatus.Running) { + + vmStarted = true; + } else if (status_changed == VMStatus.Ready || status_changed == VMStatus.Stopped) { + + } else if (status_changed == VMStatus.Saving) { + + } else if (status_changed == VMStatus.Paused) { + + } + } + }); + + } + + public static void install(boolean force) { + progDialog = ProgressDialog.show(activity, "Please Wait", "Installing BIOS...", true); + installerTaskTask = new InstallerTask(); + installerTaskTask.force = force; + installerTaskTask.execute(); + } + + public static void checkAndLoadLibs() { + if (Config.loadNativeLibsEarly) + if (Config.loadNativeLibsMainThread) + setupNativeLibs(); + else + setupNativeLibsAsync(); + } + + public static void clearNotifications() { + NotificationManager notificationManager = (NotificationManager) activity.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancelAll(); + } + + public static void setupNativeLibsAsync() { + + Thread thread = new Thread(new Runnable() { + public void run() { + setupNativeLibs(); + } + }); + thread.setPriority(Thread.MIN_PRIORITY); + thread.start(); + + } + + public static void savePendingEditText() { + View currentView = activity.getCurrentFocus(); + if (currentView != null && currentView instanceof EditText) { + ((EditText) currentView).setFocusable(false); + } + } + + public static void checkLog() { + + Thread t = new Thread(new Runnable() { + public void run() { + + if (MainSettingsManager.getExitCode(activity) != 1) { + MainSettingsManager.setExitCode(activity, 1); + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + UIUtils.promptShowLog(activity); + } + }); + } + } + }); + t.start(); + } + + public static void setupFolders() { + Thread t = new Thread(new Runnable() { + public void run() { + + Config.cacheDir = activity.getCacheDir().getAbsolutePath(); + Config.storagedir = Environment.getExternalStorageDirectory().toString(); + + // Create Temp folder + File folder = new File(Config.getTmpFolder()); + if (!folder.exists()) + folder.mkdirs(); + + + } + }); + t.start(); + } + + //XXX: sometimes this needs to be called from the main thread otherwise + // qemu crashes when it is started later + public static void setupNativeLibs() { + + if (libLoaded) + return; + + //Some devices need stl loaded upfront + //System.loadLibrary("stlport_shared"); + + //Compatibility lib + System.loadLibrary("compat-vectras"); + + //Glib deps + System.loadLibrary("compat-musl"); + + + //Glib + System.loadLibrary("glib-2.0"); + + //Pixman for qemu + System.loadLibrary("pixman-1"); + + //Spice server + if (Config.enable_SPICE) { + System.loadLibrary("crypto"); + System.loadLibrary("ssl"); + System.loadLibrary("spice"); + } + + // //Load SDL library + if (Config.enable_SDL) { + System.loadLibrary("SDL2"); + } + + System.loadLibrary("compat-SDL2-ext"); + + //Vectras needed for vmexecutor + System.loadLibrary("vectras"); + + loadQEMULib(); + + libLoaded = true; + } + + public static void loadQEMULib() { + + try { + System.loadLibrary("qemu-system-i386"); + } catch (Error ex) { + System.loadLibrary("qemu-system-x86_64"); + } + + } + + + public static void setupStrictMode() { + + if (Config.debugStrictMode) { + StrictMode.setThreadPolicy( + new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork() + //.penaltyDeath() + .penaltyLog().build()); + StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects() + .detectLeakedClosableObjects().penaltyLog() + // .penaltyDeath() + .build()); + } + + } + + public static void onLicense() { + PackageInfo pInfo = null; + + try { + pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(), PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return; + } + + final PackageInfo finalPInfo = pInfo; + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + + } + }); + + } + + // Main event function + // Retrives values from saved preferences + public static void onStartButton() { + if (MainService.isRunning) { + startvnc(); + } else { + if (vmexecutor == null) { + + try { + vmexecutor = new StartVM(activity); + } catch (Exception ex) { + UIUtils.toastLong(activity, "Error: " + ex); + return; + + } + } + // dns + vmexecutor.dns_addr = Config.defaultDNSServer; + + vmexecutor.paused = 0; + + if (!vmStarted) { + UIUtils.toastShort(activity, "Starting VM"); + //XXX: make sure that bios files are installed in case we ran out of space in the last + // run + FileInstaller.installFiles(activity, false); + } else { + UIUtils.toastShort(activity, "Connecting to VM"); + } + + if (Config.ui.equals("VNC")) { + vmexecutor.enableqmp = 1; // We enable qemu monitor + startVNC(); + + } else if (Config.ui.equals("SDL")) { + vmexecutor.enableqmp = 0; // We disable qemu monitor + startSDL(); + } else { + vmexecutor.enableqmp = 1; // We enable qemu monitor + startSPICE(); + } + } + } + + public static String getLanguageCode(int index) { + // TODO: Add more languages from /assets/roms/keymaps + switch (index) { + case 0: + return "en-us"; + case 1: + return "es"; + case 2: + return "fr"; + } + return null; + } + + public static void startSDL() { + + Thread tsdl = new Thread(new Runnable() { + public void run() { + startsdl(); + } + }); + if (Config.maxPriority) + tsdl.setPriority(Thread.MAX_PRIORITY); + tsdl.start(); + } + + public static void startVNC() { + + VncCanvas.retries = 0; + if (!vmStarted) { + + Thread tvm = new Thread(new Runnable() { + public void run() { + startvm(activity, Config.UI_VNC); + } + }); + if (Config.maxPriority) + tvm.setPriority(Thread.MAX_PRIORITY); + tvm.start(); + } else { + startvnc(); + } + + + } + + public static void startSPICE() { + + if (!vmStarted) { + + Thread tvm = new Thread(new Runnable() { + public void run() { + startvm(activity, Config.UI_SPICE); + } + }); + if (Config.maxPriority) + tvm.setPriority(Thread.MAX_PRIORITY); + tvm.start(); + } + + } + + public static void onStopButton(boolean exit) { + stopVM(exit); + } + + public static void onRestartButton() { + + execTimer(); + + Machine.resetVM(activity); + } + + public static void onResumeButton() { + + // TODO: This probably has no effect + Thread t = new Thread(new Runnable() { + public void run() { + resumevm(); + } + }); + t.start(); + } + + public static void toggleVisibility(View view) { + if (view.getVisibility() == View.VISIBLE) { + view.setVisibility(View.GONE); + } else if (view.getVisibility() == View.GONE || view.getVisibility() == View.INVISIBLE) { + view.setVisibility(View.VISIBLE); + } + } + + public static void startvnc() { + + // Wait till Qemu settles + try { + Thread.sleep(2000); + } catch (InterruptedException ex) { + Logger.getLogger(activity.getClass().getName()).log(Level.SEVERE, null, ex); + } + if (MainSettingsManager.getVncExternal(activity)) { + + } else { + connectLocally(); + } + } + + public static void promptConnectLocally(final Activity activity) { + + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + final AlertDialog alertDialog; + alertDialog = new AlertDialog.Builder(activity, R.style.MainDialogTheme).create(); + alertDialog.setTitle("VNC Started"); + TextView stateView = new TextView(activity); + stateView.setText("VNC Server started: " + getLocalIpAddress() + ":" + Config.defaultVNCPort + "\n" + + "Warning: VNC Connection is Unencrypted and not secure make sure you're on a private network!\n"); + + stateView.setPadding(20, 20, 20, 20); + alertDialog.setView(stateView); + + alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + alertDialog.dismiss(); + } + }); + alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, "Connect Locally", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + connectLocally(); } }); - if (mInterstitialAd != null && !loaded && !MainService.isRunning) { - mInterstitialAd.show(MainActivity.this); - loaded = true; + alertDialog.show(); + } + }, 100); + + + } + + public static void connectLocally() { + //UIUtils.toastShort(this, "Connecting to VM Display"); + Intent intent = getVNCIntent(); + activity.startActivityForResult(intent, Config.VNC_REQUEST_CODE); + } + + public static void startsdl() { + + Intent intent = null; + + intent = new Intent(activity, MainSDLActivity.class); + + android.content.ContentValues values = new android.content.ContentValues(); + activity.startActivityForResult(intent, Config.SDL_REQUEST_CODE); + } + + + public static void resumevm() { + if (vmexecutor != null) { + vmexecutor.resumevm(); + UIUtils.toastShort(activity, "VM Reset"); } else { - Log.d("TAG", "The interstitial ad wasn't ready yet."); + + UIUtils.toastShort(activity, "VM not running"); + } + + } + + public static Intent getVNCIntent() { + return new Intent(activity, com.vectras.qemu.MainVNCActivity.class); + + } + + + public static void goToSettings() { + Intent i = new Intent(activity, MainSettingsManager.class); + activity.startActivity(i); + } + + public static void onViewLog() { + + Thread t = new Thread(new Runnable() { + public void run() { + FileUtils.viewVectrasLog(activity); + } + }); + t.start(); + } + + public static void goToURL(String url) { + + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + activity.startActivity(i); + + } + + public static void stopVM(boolean exit) { + execTimer(); + Machine.stopVM(activity); + } + + public static void stopTimeListener() { + + synchronized (lockTime) { + timeQuit = true; + lockTime.notifyAll(); + } + } + + + public static void timer() { + //XXX: No timers just ping a few times + for (int i = 0; i < 3; i++) { + checkAndUpdateStatus(false); + + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + + } + + public static void checkAndUpdateStatus(boolean force) { + if (vmexecutor != null) { + VMStatus status = checkStatus(); + if (force || status != currStatus) { + currStatus = status; + changeStatus(status); + } + } + } + + public static void execTimer() { + + Thread t = new Thread(new Runnable() { + public void run() { + startTimer(); + } + }); + t.start(); + } + + public static void startTimer() { + stopTimeListener(); + + timeQuit = false; + try { + timer(); + } catch (Exception ex) { + ex.printStackTrace(); + + } + + } + + + public static enum VMStatus { + Ready, Stopped, Saving, Paused, Completed, Failed, Unknown, Running + } + + public static VMStatus checkStatus() { + VMStatus state = VMStatus.Ready; + if (vmexecutor != null && libLoaded && vmexecutor.get_state().toUpperCase().equals("RUNNING")) { + state = VMStatus.Running; } + return state; } + public static class InstallerTask extends AsyncTask { + public boolean force; + + @Override + protected Void doInBackground(Void... arg0) { + onInstall(force); + if (progDialog.isShowing()) { + progDialog.dismiss(); + } + return null; + } + + @Override + protected void onPostExecute(Void test) { + + } + } } 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 c3e68fc..85c9ac4 100644 --- a/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java +++ b/app/src/main/java/com/vectras/vm/MainRoms/AdapterMainRoms.java @@ -1,7 +1,6 @@ package com.vectras.vm.MainRoms; import android.app.Dialog; -import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.Bitmap; @@ -16,20 +15,13 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.vectras.qemu.Config; -import com.vectras.qemu.MainActivityCommon; -import com.vectras.qemu.MainService; -import com.vectras.qemu.MainSettingsManager; -import com.vectras.qemu.jni.StartVM; -import com.vectras.qemu.utils.Machine; import com.vectras.vm.AppConfig; import com.vectras.vm.Fragment.HomeFragment; import com.vectras.vm.MainActivity; @@ -42,9 +34,6 @@ import java.io.Writer; import java.util.Collections; import java.util.List; -import java.util.Objects; -import java.util.Timer; -import java.util.TimerTask; public class AdapterMainRoms extends RecyclerView.Adapter { @@ -82,15 +71,15 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) myHolder.cdRoms.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { - MainActivityCommon.setupNativeLibs(); + MainActivity.setupNativeLibs(); Config.hda_path = current.itemPath; Config.extra_params = current.itemExtra; Thread thread = new Thread(new Runnable() { public void run() { if (!Config.loadNativeLibsEarly && !Config.loadNativeLibsMainThread) { - MainActivityCommon.setupNativeLibs(); + MainActivity.setupNativeLibs(); } - MainActivityCommon.onStartButton(); + MainActivity.onStartButton(); } }); thread.setPriority(Thread.MIN_PRIORITY); diff --git a/app/src/main/java/com/vectras/vm/RomsManagerActivity.java b/app/src/main/java/com/vectras/vm/RomsManagerActivity.java index 044fa39..4c8a2ff 100644 --- a/app/src/main/java/com/vectras/vm/RomsManagerActivity.java +++ b/app/src/main/java/com/vectras/vm/RomsManagerActivity.java @@ -384,7 +384,7 @@ private void startIconDownload() { public void onFirstStartup() { if (selected) { - if (FileUtils.fileValid(activity, AppConfig.maindirpath + selectedPath)) { + if (FileUtils.fileValid(activity, AppConfig.maindirpath + selectedPath) && !FileUtils.fileValid(activity, AppConfig.maindirpath + "icons/" + selectedPath.replace(".IMG", ".jpg"))) { SharedPreferences credentials = activity.getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE); ProgressDialog mProgressDialog = new ProgressDialog(this, R.style.MainDialogTheme); mProgressDialog.setTitle("Data Setup"); diff --git a/app/src/main/java/com/vectras/vm/SplashActivity.java b/app/src/main/java/com/vectras/vm/SplashActivity.java index dfa9f54..10c3b64 100644 --- a/app/src/main/java/com/vectras/vm/SplashActivity.java +++ b/app/src/main/java/com/vectras/vm/SplashActivity.java @@ -1,34 +1,17 @@ package com.vectras.vm; -import static android.os.Build.VERSION.SDK_INT; - -import android.Manifest; -import android.animation.ValueAnimator; -import android.app.ActivityManager; -import android.app.Dialog; import android.content.*; import android.content.pm.*; -import android.net.Uri; import android.os.*; -import android.preference.PreferenceManager; -import android.provider.Settings; import android.view.*; -import android.graphics.*; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import com.airbnb.lottie.LottieAnimationView; import com.google.firebase.auth.FirebaseAuth; -import com.vectras.qemu.MainActivityCommon; import com.vectras.qemu.MainSettingsManager; import com.vectras.qemu.utils.RamInfo; -import com.vectras.vm.R; -import com.vectras.vm.MainActivity; import com.vectras.vm.ui.login.LoginActivity; -import com.vectras.vm.utils.UIUtils; import java.io.File; diff --git a/app/src/main/java/com/vectras/vm/utils/UIUtils.java b/app/src/main/java/com/vectras/vm/utils/UIUtils.java index c0710db..16d7beb 100644 --- a/app/src/main/java/com/vectras/vm/utils/UIUtils.java +++ b/app/src/main/java/com/vectras/vm/utils/UIUtils.java @@ -28,16 +28,12 @@ import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; import com.vectras.qemu.Config; -import com.vectras.qemu.MainActivityCommon; import com.vectras.qemu.MainSettingsManager; import com.vectras.qemu.utils.FileUtils; +import com.vectras.vm.MainActivity; import com.vectras.vm.R; -import com.vectras.vm.AppConfig; import com.vectras.vm.logger.VectrasStatus; import java.io.IOException; @@ -111,7 +107,7 @@ public static void showFileNotSupported(Activity context){ public static boolean onKeyboard(Activity activity, boolean toggle, View view) { // Prevent crashes from activating mouse when machine is paused - if (MainActivityCommon.vmexecutor.paused == 1) + if (MainActivity.vmexecutor.paused == 1) return !toggle; InputMethodManager inputMgr = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); diff --git a/app/src/main/jniLibs/arm64-v8a/libSDL2.so b/app/src/main/jniLibs/arm64-v8a/libSDL2.so new file mode 100644 index 0000000..2f4f1ee Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libSDL2.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libcompat-SDL2-ext.so b/app/src/main/jniLibs/arm64-v8a/libcompat-SDL2-ext.so new file mode 100644 index 0000000..b37176c Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libcompat-SDL2-ext.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libcompat-musl.so b/app/src/main/jniLibs/arm64-v8a/libcompat-musl.so new file mode 100644 index 0000000..60517f1 Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libcompat-musl.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libcompat-vectras.so b/app/src/main/jniLibs/arm64-v8a/libcompat-vectras.so new file mode 100644 index 0000000..27ad607 Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libcompat-vectras.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libglib-2.0.so b/app/src/main/jniLibs/arm64-v8a/libglib-2.0.so new file mode 100644 index 0000000..ee1c979 Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libglib-2.0.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libpixman-1.so b/app/src/main/jniLibs/arm64-v8a/libpixman-1.so new file mode 100644 index 0000000..77adcf9 Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libpixman-1.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libqemu-system-x86_64.so b/app/src/main/jniLibs/arm64-v8a/libqemu-system-x86_64.so new file mode 100644 index 0000000..c74069d Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libqemu-system-x86_64.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libvectras.so b/app/src/main/jniLibs/arm64-v8a/libvectras.so new file mode 100644 index 0000000..796233c Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libvectras.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libSDL2.so b/app/src/main/jniLibs/armeabi-v7a/libSDL2.so index 067ce42..4c96136 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libSDL2.so and b/app/src/main/jniLibs/armeabi-v7a/libSDL2.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libcompat-SDL2-ext.so b/app/src/main/jniLibs/armeabi-v7a/libcompat-SDL2-ext.so index b69b20a..cd63df6 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libcompat-SDL2-ext.so and b/app/src/main/jniLibs/armeabi-v7a/libcompat-SDL2-ext.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libcompat-musl.so b/app/src/main/jniLibs/armeabi-v7a/libcompat-musl.so index 1585c61..5139c39 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libcompat-musl.so and b/app/src/main/jniLibs/armeabi-v7a/libcompat-musl.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libcompat-vectras.so b/app/src/main/jniLibs/armeabi-v7a/libcompat-vectras.so index aa2ef38..ad55c7e 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libcompat-vectras.so and b/app/src/main/jniLibs/armeabi-v7a/libcompat-vectras.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libqemu-system-x86_64.so b/app/src/main/jniLibs/armeabi-v7a/libqemu-system-x86_64.so index 72b771b..eac556e 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libqemu-system-x86_64.so and b/app/src/main/jniLibs/armeabi-v7a/libqemu-system-x86_64.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libvectras.so b/app/src/main/jniLibs/armeabi-v7a/libvectras.so index 9d93316..d68e6d9 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libvectras.so and b/app/src/main/jniLibs/armeabi-v7a/libvectras.so differ diff --git a/app/src/main/jniLibs/x86/libSDL2.so b/app/src/main/jniLibs/x86/libSDL2.so new file mode 100644 index 0000000..6e5e6a7 Binary files /dev/null and b/app/src/main/jniLibs/x86/libSDL2.so differ diff --git a/app/src/main/jniLibs/x86/libcompat-SDL2-ext.so b/app/src/main/jniLibs/x86/libcompat-SDL2-ext.so new file mode 100644 index 0000000..ce47588 Binary files /dev/null and b/app/src/main/jniLibs/x86/libcompat-SDL2-ext.so differ diff --git a/app/src/main/jniLibs/x86/libcompat-musl.so b/app/src/main/jniLibs/x86/libcompat-musl.so new file mode 100644 index 0000000..4c700ef Binary files /dev/null and b/app/src/main/jniLibs/x86/libcompat-musl.so differ diff --git a/app/src/main/jniLibs/x86/libcompat-vectras.so b/app/src/main/jniLibs/x86/libcompat-vectras.so new file mode 100644 index 0000000..08d36a4 Binary files /dev/null and b/app/src/main/jniLibs/x86/libcompat-vectras.so differ diff --git a/app/src/main/jniLibs/x86/libglib-2.0.so b/app/src/main/jniLibs/x86/libglib-2.0.so new file mode 100644 index 0000000..b9d97c4 Binary files /dev/null and b/app/src/main/jniLibs/x86/libglib-2.0.so differ diff --git a/app/src/main/jniLibs/x86/libpixman-1.so b/app/src/main/jniLibs/x86/libpixman-1.so new file mode 100644 index 0000000..e9e9237 Binary files /dev/null and b/app/src/main/jniLibs/x86/libpixman-1.so differ diff --git a/app/src/main/jniLibs/x86/libqemu-system-x86_64.so b/app/src/main/jniLibs/x86/libqemu-system-x86_64.so new file mode 100644 index 0000000..a186e44 Binary files /dev/null and b/app/src/main/jniLibs/x86/libqemu-system-x86_64.so differ diff --git a/app/src/main/jniLibs/x86/libvectras.so b/app/src/main/jniLibs/x86/libvectras.so new file mode 100644 index 0000000..2204139 Binary files /dev/null and b/app/src/main/jniLibs/x86/libvectras.so differ diff --git a/app/src/main/jniLibs/x86_64/libSDL2.so b/app/src/main/jniLibs/x86_64/libSDL2.so new file mode 100644 index 0000000..81153de Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libSDL2.so differ diff --git a/app/src/main/jniLibs/x86_64/libcompat-SDL2-ext.so b/app/src/main/jniLibs/x86_64/libcompat-SDL2-ext.so new file mode 100644 index 0000000..7de6f5d Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libcompat-SDL2-ext.so differ diff --git a/app/src/main/jniLibs/x86_64/libcompat-musl.so b/app/src/main/jniLibs/x86_64/libcompat-musl.so new file mode 100644 index 0000000..79cffca Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libcompat-musl.so differ diff --git a/app/src/main/jniLibs/x86_64/libcompat-vectras.so b/app/src/main/jniLibs/x86_64/libcompat-vectras.so new file mode 100644 index 0000000..0e2b485 Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libcompat-vectras.so differ diff --git a/app/src/main/jniLibs/x86_64/libglib-2.0.so b/app/src/main/jniLibs/x86_64/libglib-2.0.so new file mode 100644 index 0000000..44e4c93 Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libglib-2.0.so differ diff --git a/app/src/main/jniLibs/x86_64/libpixman-1.so b/app/src/main/jniLibs/x86_64/libpixman-1.so new file mode 100644 index 0000000..e95532e Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libpixman-1.so differ diff --git a/app/src/main/jniLibs/x86_64/libqemu-system-x86_64.so b/app/src/main/jniLibs/x86_64/libqemu-system-x86_64.so new file mode 100644 index 0000000..5d557df Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libqemu-system-x86_64.so differ diff --git a/app/src/main/jniLibs/x86_64/libvectras.so b/app/src/main/jniLibs/x86_64/libvectras.so new file mode 100644 index 0000000..9f412d0 Binary files /dev/null and b/app/src/main/jniLibs/x86_64/libvectras.so differ diff --git a/app/src/main/res/drawable/round_dns_24.xml b/app/src/main/res/drawable/round_dns_24.xml new file mode 100644 index 0000000..a43abcc --- /dev/null +++ b/app/src/main/res/drawable/round_dns_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 77655be..701969a 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -19,8 +19,8 @@ diff --git a/app/src/main/res/layout/main_content.xml b/app/src/main/res/layout/main_content.xml index 5ad1842..6a3b355 100644 --- a/app/src/main/res/layout/main_content.xml +++ b/app/src/main/res/layout/main_content.xml @@ -29,99 +29,85 @@ android:layout_gravity="center" android:orientation="vertical"> - + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_margin="8dp" + android:background="?attr/colorSurface" + app:cardCornerRadius="10dp" + app:cardElevation="2dp" + app:cardUseCompatPadding="false"> + android:fitsSystemWindows="true" + android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - + android:minWidth="190dp" + android:padding="4dp" + android:text="@string/memory_usage" /> + + + + + + + + + + + + - + + @@ -140,10 +126,10 @@ android:id="@+id/nestedScrollView" android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_marginBottom="76dp" android:layout_weight="1.0" android:fillViewport="true" android:orientation="vertical" - android:layout_marginBottom="76dp" app:layout_behavior="@string/appbar_scrolling_view_behavior"> + app:layout_constraintStart_toStartOf="parent" /> \ No newline at end of file diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml index c103508..951f4eb 100644 --- a/app/src/main/res/layout/nav_header_main.xml +++ b/app/src/main/res/layout/nav_header_main.xml @@ -106,6 +106,7 @@ android:orientation="vertical"> + + + + \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index 0a077b1..83a55a0 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -128,4 +128,8 @@ @anim/slide_in_bottom @anim/slide_out_bottom + \ 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 0611a7b..bbfac0e 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -7,8 +7,6 @@ 4 core 5 core 6 core - 7 core - 8 core 1 @@ -17,7 +15,5 @@ 4 5 6 - 7 - 8 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b81dd66..77ec6e6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ Vectras VM - 2.1 + 2.2 Home Logger Start Emulation diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e30dfca..ae2dd8c 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -129,4 +129,8 @@ @anim/slide_in_bottom @anim/slide_out_bottom + \ No newline at end of file diff --git a/app/src/main/res/xml/qemu.xml b/app/src/main/res/xml/qemu.xml index 8d0c693..24f20a9 100644 --- a/app/src/main/res/xml/qemu.xml +++ b/app/src/main/res/xml/qemu.xml @@ -23,6 +23,9 @@ android:selectAllOnFocus="true" android:singleLine="true" android:title="MEMORY" + android:enabled="false" + android:shouldDisableView="true" + app:shouldDisableView="true" app:icon="@drawable/round_memory_24" /> + \ No newline at end of file diff --git a/screenshots/Screen_recording_1.mp4 b/screenshots/Screen_recording_1.mp4 new file mode 100644 index 0000000..3371dd9 Binary files /dev/null and b/screenshots/Screen_recording_1.mp4 differ diff --git a/screenshots/Screenshot_homescreen.png b/screenshots/Screenshot_homescreen.png new file mode 100644 index 0000000..d62ce98 Binary files /dev/null and b/screenshots/Screenshot_homescreen.png differ diff --git a/screenshots/Screenshot_homescreen2.png b/screenshots/Screenshot_homescreen2.png new file mode 100644 index 0000000..d7e5f31 Binary files /dev/null and b/screenshots/Screenshot_homescreen2.png differ diff --git a/screenshots/Screenshot_loggerscreen.png b/screenshots/Screenshot_loggerscreen.png new file mode 100644 index 0000000..102ec87 Binary files /dev/null and b/screenshots/Screenshot_loggerscreen.png differ diff --git a/screenshots/Screenshot_reactos1.png b/screenshots/Screenshot_reactos1.png new file mode 100644 index 0000000..5038839 Binary files /dev/null and b/screenshots/Screenshot_reactos1.png differ diff --git a/screenshots/Screenshot_romsscreen1.png b/screenshots/Screenshot_romsscreen1.png new file mode 100644 index 0000000..2c5284e Binary files /dev/null and b/screenshots/Screenshot_romsscreen1.png differ diff --git a/screenshots/Screenshot_romsscreen2.png b/screenshots/Screenshot_romsscreen2.png new file mode 100644 index 0000000..5e0a2cf Binary files /dev/null and b/screenshots/Screenshot_romsscreen2.png differ diff --git a/screenshots/Screenshot_settings.png b/screenshots/Screenshot_settings.png new file mode 100644 index 0000000..72b649a Binary files /dev/null and b/screenshots/Screenshot_settings.png differ diff --git a/screenshots/Screenshot_settingsqemu.png b/screenshots/Screenshot_settingsqemu.png new file mode 100644 index 0000000..ee5ed1e Binary files /dev/null and b/screenshots/Screenshot_settingsqemu.png differ