mirror of
https://github.com/xoureldeen/Vectras-VM-Android.git
synced 2026-05-05 17:56:59 +00:00
gg
This commit is contained in:
parent
0161c73c0c
commit
9edcda8d1e
480 changed files with 2 additions and 69750 deletions
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Max Kastanas 2012
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
package com.vectras.qemu;
|
||||
|
||||
import android.androidVNC.COLORMODEL;
|
||||
import android.androidVNC.VncCanvasActivity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Environment;
|
||||
import android.widget.ImageView.ScaleType;
|
||||
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.SplashActivity;
|
||||
import com.vectras.vm.VectrasApp;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author dev
|
||||
*/
|
||||
public class Config {
|
||||
|
||||
// Constants
|
||||
public static final int UI_VNC = 0;
|
||||
public static final int UI_SDL = 1;
|
||||
public static final int UI_SPICE = 2;
|
||||
public static final int SDL_MOUSE_LEFT = 1;
|
||||
public static final int SDL_MOUSE_MIDDLE = 2;
|
||||
public static final int SDL_MOUSE_RIGHT = 3;
|
||||
public static final int VNC_REQUEST_CODE = 1004;
|
||||
public static final int VNC_RESET_RESULT_CODE = 1006;
|
||||
public static final int SDL_REQUEST_CODE = 1007;
|
||||
public static final String ACTION_START = "com.vectras.qemu.action.STARTVM";
|
||||
|
||||
// GUI Options
|
||||
public static final boolean enable_SDL = true;
|
||||
public static final boolean enable_SPICE = false;
|
||||
|
||||
public static final boolean enable_qemu_fullScreen = true;
|
||||
|
||||
// App config
|
||||
public static final String APP_NAME = "Vectras Emulator";
|
||||
public static String storagedir = null;
|
||||
|
||||
//Some OSes don't like emulated multi cores for QEMU 2.9.1 you can disable here
|
||||
/// thought there is also the Disable TSC feature so you don't have to do it here
|
||||
public static boolean enableSMPOnlyOnKVM = false;
|
||||
|
||||
//set to true if you need to debug native library loading
|
||||
public static boolean loadNativeLibsEarly = false;
|
||||
|
||||
//XXX: QEMU 3.1.0 needs the libraries to be loaded from the main thread
|
||||
public static boolean loadNativeLibsMainThread = true;
|
||||
|
||||
public static String wakeLockTag = "vectras:wakelock";
|
||||
public static String wifiLockTag = "vectras:wifilock";
|
||||
|
||||
//this will be populated later
|
||||
public static String cacheDir = null;
|
||||
|
||||
//we disable mouse modes for now
|
||||
public static boolean disableMouseModes = true;
|
||||
|
||||
//double tap an hold is still buggy so we keep using the old-way trackpad
|
||||
public static boolean enableDragOnLongPress = true;
|
||||
|
||||
//we need to define the configuration for the VNC client since we replaced some deprecated
|
||||
// functions
|
||||
public static Bitmap.Config bitmapConfig = Bitmap.Config.RGB_565;
|
||||
|
||||
//XXX set scaling to linear it's a tad slower but it's worth it
|
||||
public static int SDLHintScale=1;
|
||||
public static boolean viewLogInternally = true;
|
||||
|
||||
|
||||
//XXX some archs don't support floppy or sd card
|
||||
public static boolean enableEmulatedFloppy = true;
|
||||
public static boolean enableEmulatedSDCard;
|
||||
public static String destLogFilename = "vectraslog.txt";
|
||||
|
||||
public static String notificationChannelID = "vectras";
|
||||
public static String notificationChannelName = "vectras";
|
||||
public static boolean showToast = false;
|
||||
public static boolean closeFileDescriptors = true;
|
||||
public static String hda_path;
|
||||
public static String extra_params;
|
||||
|
||||
|
||||
public static final String getCacheDir(){
|
||||
return cacheDir.toString();
|
||||
}
|
||||
public static final String getBasefileDir() {
|
||||
return AppConfig.basefiledir;
|
||||
}
|
||||
|
||||
public static String machineFolder = "machines/";
|
||||
public static String getMachineDir(){
|
||||
return getBasefileDir() + machineFolder;
|
||||
}
|
||||
public static String logFilePath = cacheDir + "/vectras/vectras-log.txt";
|
||||
|
||||
|
||||
public static final String defaultDNSServer = "8.8.8.8";
|
||||
public static String state_filename = "vm.state";
|
||||
|
||||
//QMP
|
||||
public static String QMPServer = "127.0.0.1";
|
||||
public static int QMPPort = 4444;
|
||||
|
||||
public static int MAX_DISPLAY_REFRESH_RATE = 100; //Hz
|
||||
|
||||
// VNC Defaults
|
||||
public static String defaultVNCHost = "127.0.0.1";
|
||||
public static final String defaultVNCUsername = "vectras";
|
||||
public static final String defaultVNCPasswd = "";
|
||||
|
||||
//It seems that for new veersion of qemu it expectes a relative number
|
||||
// so we stop using absolute port numbers
|
||||
public static final int defaultVNCPort = 1;
|
||||
|
||||
public static final String defaultVNCColorMode = COLORMODEL.C24bit.nameString();
|
||||
public static final ScaleType defaultFullscreenScaleMode = ScaleType.FIT_CENTER;
|
||||
public static final ScaleType defaultScaleModeCenter = ScaleType.CENTER;
|
||||
public static final String defaultInputMode = VncCanvasActivity.TOUCH_ZOOM_MODE;
|
||||
|
||||
//Keyboard Layout
|
||||
public static String defaultKeyboardLayout = "en-us";
|
||||
|
||||
|
||||
public static boolean enableToggleKeyboard = false;
|
||||
// Debug
|
||||
public static final boolean debug = false;
|
||||
public static boolean debugQmp = false;
|
||||
|
||||
//remove in production
|
||||
public static boolean debugStrictMode = false;
|
||||
|
||||
public static boolean processMouseHistoricalEvents = false;
|
||||
|
||||
public static String getLocalQMPSocketPath() {
|
||||
return Config.getCacheDir()+"/qmpsocket";
|
||||
}
|
||||
|
||||
public static String getLocalVNCSocketPath() {
|
||||
return Config.getCacheDir()+"/vncsocket";
|
||||
}
|
||||
|
||||
public static enum MouseMode {
|
||||
Trackpad, External
|
||||
}
|
||||
public static MouseMode mouseMode = MouseMode.Trackpad;
|
||||
|
||||
//specify hd interface, alternative we don't need it right now
|
||||
public static boolean enable_hd_if = true;
|
||||
public static String hd_if_type = "ide";
|
||||
|
||||
//Change to true in prod if you want to be notified by default for new versions
|
||||
public static boolean defaultCheckNewVersion = true;
|
||||
|
||||
// App config
|
||||
public static final String datadirpath = VectrasApp.getApp().getExternalFilesDir("data")+"/";
|
||||
public static final String sharedFolder = datadirpath + "Vectras/ProgramFiles/";
|
||||
|
||||
public static String machinename = "VECTRAS";
|
||||
public static int paused = 0;
|
||||
public static String ui = "VNC";
|
||||
public static boolean maxPriority = false;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,242 +0,0 @@
|
|||
package com.vectras.qemu;
|
||||
|
||||
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiManager.WifiLock;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.vectras.qemu.jni.StartVM;
|
||||
import com.vectras.qemu.utils.FileUtils;
|
||||
import com.vectras.vm.Fragment.HomeFragment;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.R;
|
||||
|
||||
public class MainService extends Service {
|
||||
|
||||
private static final String TAG = "MainService";
|
||||
private static Notification mNotification;
|
||||
private static WifiLock mWifiLock;
|
||||
public static MainService service;
|
||||
private static WakeLock mWakeLock;
|
||||
public static boolean isRunning;
|
||||
private NotificationManager mNotificationManager;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static StartVM executor;
|
||||
private static NotificationCompat.Builder builder;
|
||||
|
||||
public static final int notifID = 1000;
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
final String action = intent.getAction();
|
||||
final Bundle b = intent.getExtras();
|
||||
final int ui = b.getInt("ui", 0);
|
||||
|
||||
if (action.equals(Config.ACTION_START)) {
|
||||
setUpAsForeground(Config.machinename + " VM Running");
|
||||
|
||||
FileUtils.startLogging();
|
||||
|
||||
scheduleTimer();
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
//XXX: wait till logging starts capturing
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Log.v(TAG, "Starting VM " + Config.machinename);
|
||||
|
||||
setupLocks();
|
||||
|
||||
if (ui == Config.UI_VNC) {
|
||||
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
MainActivity.startvnc();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
//Start vm
|
||||
String res = executor.startvm();
|
||||
|
||||
//VM has exited
|
||||
MainActivity.cleanup();
|
||||
|
||||
}
|
||||
});
|
||||
t.setName("StartVM");
|
||||
t.start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Don't restart if killed
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
private void scheduleTimer() {
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
MainActivity.startTimer();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
||||
private void setUpAsForeground(String text) {
|
||||
isRunning = true;
|
||||
MainActivity.vmStarted = true;
|
||||
Class<?> clientClass = null;
|
||||
if (Config.ui != null) {
|
||||
if (Config.ui.equals("VNC")) {
|
||||
if (MainSettingsManager.getVncExternal(MainActivity.activity)) {
|
||||
MainActivity.extVncLayout.setVisibility(View.VISIBLE);
|
||||
MainActivity.appbar.setExpanded(true);
|
||||
}
|
||||
clientClass = MainVNCActivity.class;
|
||||
} else if (Config.ui.equals("SDL")) {
|
||||
clientClass = MainSDLActivity.class;
|
||||
} else {
|
||||
Log.e(TAG, "Unknown User Interface");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// UIUtils.toastLong(service, "Machine UI is not set");
|
||||
//using VNC by default
|
||||
clientClass = MainVNCActivity.class;
|
||||
}
|
||||
Intent intent = new Intent(service.getApplicationContext(), clientClass);
|
||||
|
||||
PendingIntent pi = PendingIntent.getActivity(service.getApplicationContext(), 0, intent,
|
||||
PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel chan = new NotificationChannel(Config.notificationChannelID, Config.notificationChannelName, NotificationManager.IMPORTANCE_NONE);
|
||||
NotificationManager notifService = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notifService.createNotificationChannel(chan);
|
||||
builder = new NotificationCompat.Builder(service, Config.notificationChannelID);
|
||||
|
||||
} else
|
||||
builder = new NotificationCompat.Builder(service, "");
|
||||
mNotification = builder.setContentIntent(pi).setContentTitle(getString(R.string.app_name)).setContentText(text)
|
||||
.setSmallIcon(R.mipmap.ic_launcher)
|
||||
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.mipmap.ic_launcher)).build();
|
||||
mNotification.tickerText = text;
|
||||
mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 34) {
|
||||
service.startForeground(notifID, mNotification, FOREGROUND_SERVICE_TYPE_LOCATION);
|
||||
} else {
|
||||
service.startForeground(notifID, mNotification);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void updateServiceNotification(String text) {
|
||||
if (builder != null) {
|
||||
builder.setContentText(text);
|
||||
mNotification = builder.build();
|
||||
// mNotification.tickerText = text ;
|
||||
|
||||
NotificationManager mNotificationManager = (NotificationManager)
|
||||
service.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
// mId allows you to update the notification later on.
|
||||
mNotificationManager.notify(notifID, mNotification);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Log.d(TAG, "Creating Service");
|
||||
service = this;
|
||||
}
|
||||
|
||||
private void setupLocks() {
|
||||
|
||||
mWifiLock = ((WifiManager) service.getApplicationContext().getSystemService(Context.WIFI_SERVICE))
|
||||
.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, Config.wifiLockTag);
|
||||
mWifiLock.setReferenceCounted(false);
|
||||
|
||||
PowerManager pm = (PowerManager) service.getApplicationContext().getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Config.wakeLockTag);
|
||||
mWakeLock.setReferenceCounted(false);
|
||||
|
||||
mNotificationManager = (NotificationManager) service.getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
}
|
||||
|
||||
private static void releaseLocks() {
|
||||
|
||||
if (mWifiLock != null && mWifiLock.isHeld()) {
|
||||
Log.d(TAG, "Release Wifi lock...");
|
||||
mWifiLock.release();
|
||||
}
|
||||
|
||||
if (mWakeLock != null && mWakeLock.isHeld()) {
|
||||
Log.d(TAG, "Release Wake lock...");
|
||||
mWakeLock.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void stopService() {
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
releaseLocks();
|
||||
if (service != null) {
|
||||
service.stopForeground(true);
|
||||
service.stopSelf();
|
||||
isRunning = false;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
t.setName("StartVM");
|
||||
t.start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,896 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Max Kastanas 2012
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
package com.vectras.qemu;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
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;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
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 com.vectras.vm.VectrasApp;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class MainSettingsManager extends AppCompatActivity
|
||||
implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
||||
public static MainSettingsManager activity;
|
||||
|
||||
private static Handler mHandler;
|
||||
public static SharedPreferences sp;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// TODO: Implement this method
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
|
||||
activity = this;
|
||||
|
||||
sp = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp() {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class MainPreferencesFragment extends PreferenceFragmentCompat
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
@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.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 Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
@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.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 Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void onNightMode() {
|
||||
if (MainSettingsManager.getModeNight(activity)) {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
VectrasApp.getApp().setTheme(R.style.AppTheme);
|
||||
} else {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||
VectrasApp.getApp().setTheme(R.style.AppTheme);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
if (SDK_INT > 33)
|
||||
findPreference("sharedFolder").setEnabled(false);
|
||||
|
||||
mHandler = new Handler();
|
||||
Preference pref = findPreference("vmArch");
|
||||
if (pref != null) {
|
||||
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(@NonNull Preference preference,
|
||||
Object newValue) {
|
||||
onArch();
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
Preference pref2 = findPreference("kvm");
|
||||
if (pref2 != null) {
|
||||
pref2.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(@NonNull Preference preference,
|
||||
Object newValue) {
|
||||
onKvm();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onKvm() {
|
||||
if (getKvm(activity))
|
||||
setMTTCG(activity, true);
|
||||
else
|
||||
setMTTCG(activity, false);
|
||||
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);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
Preference pref3 = findPreference("MTTCG");
|
||||
if (pref3 != null) {
|
||||
pref3.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(@NonNull Preference preference,
|
||||
Object newValue) {
|
||||
onMttcg();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onMttcg() {
|
||||
if (getMTTCG(activity))
|
||||
setKvm(activity, true);
|
||||
else
|
||||
setKvm(activity, false);
|
||||
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);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
/*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;
|
||||
}
|
||||
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
||||
private void onMemory() {
|
||||
//findPreference("memory").setEnabled(sp.getBoolean("customMemory", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
onMemory();
|
||||
if (SDK_INT > 33)
|
||||
findPreference("sharedFolder").setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
onMemory();
|
||||
if (SDK_INT > 33)
|
||||
findPreference("sharedFolder").setEnabled(false);
|
||||
}
|
||||
|
||||
private void onArch() {
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent startActivity = new Intent(getContext(), SplashActivity.class);
|
||||
int pendingIntentId = 123456;
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
AlarmManager mgr = (AlarmManager) MainSettingsManager.activity.getSystemService(Context.ALARM_SERVICE);
|
||||
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle bundle, String root_key) {
|
||||
// Load the Preferences from the XML file
|
||||
setPreferencesFromResource(R.xml.qemu, root_key);
|
||||
if (SDK_INT > 33)
|
||||
findPreference("sharedFolder").setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference pref, Object newValue) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VncPreferencesFragment extends PreferenceFragmentCompat
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
@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.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);
|
||||
}
|
||||
|
||||
public static void setDNSServer(Activity activity, String dnsServer) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("dnsServer", dnsServer);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static boolean getVncExternal(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("vncExternal", false);
|
||||
}
|
||||
|
||||
public static void setVncExternal(Activity activity, boolean vncExternal) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("vncExternal", vncExternal);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static int getOrientationSetting(Activity activity) {
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
int orientation = prefs.getInt("orientation", 0);
|
||||
// UIUtils.log("Getting First time: " + firstTime);
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public static void setOrientationSetting(Activity activity, int orientation) {
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putInt("orientation", orientation);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
|
||||
public static boolean getPromptUpdateVersion(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("updateVersionPrompt", Config.defaultCheckNewVersion);
|
||||
}
|
||||
|
||||
|
||||
public static void setPromptUpdateVersion(Activity activity, boolean flag) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("updateVersionPrompt", flag);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
static boolean getPrio(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("HighPrio", false);
|
||||
}
|
||||
|
||||
public static void setPrio(Activity activity, boolean flag) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("HighPrio", flag);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
public static boolean getAlwaysShowMenuToolbar(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("AlwaysShowMenuToolbar", false);
|
||||
}
|
||||
|
||||
public static void setAlwaysShowMenuToolbar(Activity activity, boolean flag) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("AlwaysShowMenuToolbar", flag);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
public static boolean getFullscreen(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("ShowFullscreen", true);
|
||||
}
|
||||
|
||||
public static void setFullscreen(Activity activity, boolean flag) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("ShowFullscreen", flag);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
public static boolean getDesktopMode(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("DesktopMode", false);
|
||||
}
|
||||
|
||||
public static void setDesktopMode(Activity activity, boolean flag) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("DesktopMode", flag);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
public static boolean getEnableLegacyFileManager(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("EnableLegacyFileManager", false);
|
||||
}
|
||||
|
||||
|
||||
public static void setEnableLegacyFileManager(Activity activity, boolean flag) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("EnableLegacyFileManager", flag);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
public static String getLastDir(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String imagesDir = prefs.getString("lastDir", null);
|
||||
return imagesDir;
|
||||
}
|
||||
|
||||
public static void setLastDir(Context context, String imagesPath) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("lastDir", imagesPath);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public static String getImagesDir(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String imagesDir = prefs.getString("imagesDir", null);
|
||||
return imagesDir;
|
||||
}
|
||||
|
||||
public static void setImagesDir(Context context, String imagesPath) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("imagesDir", imagesPath);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
|
||||
public static String getExportDir(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String imagesDir = prefs.getString("exportDir", null);
|
||||
return imagesDir;
|
||||
}
|
||||
|
||||
public static void setExportDir(Context context, String imagesPath) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("exportDir", imagesPath);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
|
||||
public static String getSharedDir(Context context) {
|
||||
String lastDir = Environment.getExternalStorageDirectory().getPath();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return prefs.getString("sharedDir", lastDir);
|
||||
}
|
||||
|
||||
public static void setSharedDir(Context context, String lastDir) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("sharedDir", lastDir);
|
||||
edit.apply();
|
||||
// UIUtils.log("Setting First time: ");
|
||||
}
|
||||
|
||||
|
||||
public static Boolean getMTTCG(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
Boolean MTTCG = prefs.getBoolean("MTTCG", true);
|
||||
return MTTCG;
|
||||
}
|
||||
|
||||
public static void setMTTCG(Context context, Boolean MTTCG) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("MTTCG", MTTCG);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public static int getCpuCores(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int cpuCores = prefs.getInt("cpuCores", 1);
|
||||
return cpuCores;
|
||||
}
|
||||
|
||||
public static void setCpuCores(Context context, int cpuCores) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putInt("cpuCores", cpuCores);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public static int getExitCode(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int exitCode = prefs.getInt("exitCode", 1);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
public static void setExitCode(Context context, int exitCode) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putInt("exitCode", exitCode);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public static int getCpuNum(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int cpuNum = Integer.parseInt(prefs.getString("cpuNum", "1"));
|
||||
return cpuNum;
|
||||
}
|
||||
|
||||
public static void setCpuNum(Context context, String cpuNum) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("cpuNum", cpuNum);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public static String getControlMode(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String controlMode = prefs.getString("controlMode", "D");
|
||||
return controlMode;
|
||||
}
|
||||
|
||||
public static void setControlMode(Context context, String controlMode) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("controlMode", controlMode);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
|
||||
public static void setModeNight(Context context, Boolean nightMode) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("modeNight", nightMode);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
public static Boolean getModeNight(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return prefs.getBoolean("modeNight", false);
|
||||
}
|
||||
|
||||
public static void setCusRam(Activity activity, Boolean cusRam) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("customMemory", cusRam);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static boolean getCusRam(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(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 void setAvx(Activity activity, boolean AVX) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("AVX", AVX);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static boolean getAvx(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("AVX", false);
|
||||
}
|
||||
|
||||
public static void setTbSize(Activity activity, String TbSize) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("TbSize", TbSize);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getTbSize(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("TbSize", "2048");
|
||||
}
|
||||
|
||||
public static void setBoot(Activity activity, String boot) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("boot", boot);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getBoot(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("boot", "c");
|
||||
}
|
||||
|
||||
|
||||
public static void setCpu(Activity activity, String cpu) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("cpu", cpu);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getCpu(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("cpu", "qemu64");
|
||||
}
|
||||
|
||||
|
||||
public static void setVmUi(Activity activity, String vmUi) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("vmUi", vmUi);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getVmUi(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("vmUi", "SDL");
|
||||
}
|
||||
public static void setSoundCard(Activity activity, String soundCard) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("soundCard", soundCard);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getSoundCard(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("soundCard", "None");
|
||||
}
|
||||
|
||||
public static void setUsbTablet(Activity activity, boolean UsbTablet) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("UsbTablet", UsbTablet);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static boolean getUsbTablet(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("UsbTablet", false);
|
||||
}
|
||||
|
||||
public static void setCustomParams(Activity activity, String customParams) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("customParams", customParams);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getCustomParams(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("customParams", "");
|
||||
}
|
||||
|
||||
public static void setSharedFolder(Activity activity, boolean customParams) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("customParams", customParams);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static boolean getSharedFolder(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("sharedFolder", false);
|
||||
}
|
||||
|
||||
public static void setArch(Activity activity, String vmArch) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("vmArch", vmArch);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static String getArch(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getString("vmArch", "X86_64");
|
||||
}
|
||||
|
||||
public static void setKvm(Activity activity, boolean kvm) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("kvm", kvm);
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
public static boolean getKvm(Activity activity) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
return prefs.getBoolean("kvm", false);
|
||||
}
|
||||
|
||||
public static boolean isFirstLaunch(Activity activity) {
|
||||
PackageInfo pInfo = null;
|
||||
|
||||
try {
|
||||
pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(),
|
||||
PackageManager.GET_META_DATA);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
boolean firstTime = prefs.getBoolean("firstTime" + pInfo.versionName, true);
|
||||
return firstTime;
|
||||
}
|
||||
|
||||
public static void setFirstLaunch(Activity activity) {
|
||||
PackageInfo pInfo = null;
|
||||
|
||||
try {
|
||||
pInfo = activity.getPackageManager().getPackageInfo(activity.getClass().getPackage().getName(),
|
||||
PackageManager.GET_META_DATA);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putBoolean("firstTime" + pInfo.versionName, false);
|
||||
edit.commit();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,100 +0,0 @@
|
|||
package com.vectras.qemu;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.EditTextPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.SwitchPreferenceCompat;
|
||||
|
||||
import com.vectras.qemu.utils.Machine;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.SplashActivity;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
private Handler mHandler;
|
||||
public SharedPreferences mPref;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
|
||||
setPreferencesFromResource(R.xml.settings, rootKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mHandler = new Handler();
|
||||
SharedPreferences.OnSharedPreferenceChangeListener listener;
|
||||
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||
switch (key) {
|
||||
|
||||
case "modeNight":
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent startActivity = new Intent(getContext(), SplashActivity.class);
|
||||
int pendingIntentId = 123456;
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), pendingIntentId, startActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||
|
||||
AlarmManager mgr = (AlarmManager) MainSettingsManager.activity.getSystemService(Context.ALARM_SERVICE);
|
||||
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
getActivity().finish();
|
||||
break;
|
||||
case "customMemory":
|
||||
if (prefs.getBoolean("customMemory", false))
|
||||
findPreference("memory").setEnabled(true);
|
||||
else
|
||||
findPreference("memory").setEnabled(false);
|
||||
break;
|
||||
case "MTTCG":
|
||||
if (prefs.getBoolean("MTTCG", false)) {
|
||||
findPreference("cpuNum").setEnabled(false);
|
||||
MainSettingsManager.setCpuCores(getContext(), 1);
|
||||
} else {
|
||||
findPreference("cpuNum").setEnabled(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mPref = getPreferenceManager().getDefaultSharedPreferences(getContext());
|
||||
if (mPref != null) {
|
||||
mPref.registerOnSharedPreferenceChangeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mPref.getBoolean("customMemory", false))
|
||||
findPreference("memory").setEnabled(true);
|
||||
else
|
||||
findPreference("memory").setEnabled(false);
|
||||
|
||||
if (mPref.getBoolean("MTTCG", false)) {
|
||||
findPreference("cpuNum").setEnabled(false);
|
||||
} else {
|
||||
findPreference("cpuNum").setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,939 +0,0 @@
|
|||
package com.vectras.qemu.jni;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSDLActivity;
|
||||
import com.vectras.qemu.MainService;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.qemu.utils.FileUtils;
|
||||
import com.vectras.qemu.utils.Machine;
|
||||
import com.vectras.qemu.utils.QmpClient;
|
||||
import com.vectras.qemu.utils.RamInfo;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.logger.VectrasStatus;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class StartVM {
|
||||
|
||||
private static final String TAG = "StartVM";
|
||||
private static Context context;
|
||||
|
||||
String[] params = null;
|
||||
|
||||
//native lib
|
||||
private String libqemu = null;
|
||||
|
||||
//qmp server
|
||||
public int enableqmp;
|
||||
private String qmp_server;
|
||||
private int qmp_port;
|
||||
|
||||
//state
|
||||
public int paused;
|
||||
public String snapshot_name = null;
|
||||
public String save_state_name = null;
|
||||
private String save_dir;
|
||||
public int current_fd = 0;
|
||||
|
||||
public String base_dir;
|
||||
public String dns_addr;
|
||||
public String append = "";
|
||||
public boolean busy = false;
|
||||
public String name;
|
||||
|
||||
//ui
|
||||
public int enablespice = 0;
|
||||
public String keyboard_layout = Config.defaultKeyboardLayout;
|
||||
|
||||
public String mouse = null;
|
||||
public int enablevnc;
|
||||
public int vnc_allow_external = 0;
|
||||
public int qmp_allow_external = 0;
|
||||
public String vnc_passwd = "vectras";
|
||||
|
||||
// cpu/board settings
|
||||
public String cpu;
|
||||
private String arch = "x86";
|
||||
private String machine_type;
|
||||
public int memory = 128;
|
||||
private int cpuNum = 1;
|
||||
public int enablekvm;
|
||||
public int enable_mttcg;
|
||||
|
||||
// disks
|
||||
public String hda_img_path;
|
||||
public String hdb_img_path = null;
|
||||
public String hdc_img_path;
|
||||
public String hdd_img_path;
|
||||
public String shared_folder_path = null;
|
||||
public int shared_folder_readonly = 1;
|
||||
public String hd_cache = "default";
|
||||
|
||||
//removable devices
|
||||
public String cd_iso_path;
|
||||
public String fda_img_path;
|
||||
public String fdb_img_path;
|
||||
public String sd_img_path;
|
||||
|
||||
//boot options
|
||||
public String bootdevice = null;
|
||||
private String kernel;
|
||||
private String initrd;
|
||||
|
||||
//graphics
|
||||
public String vga_type = "Default";
|
||||
|
||||
//audio
|
||||
public String sound_card;
|
||||
|
||||
// net
|
||||
public String net_cfg = "None";
|
||||
public String nic_card = null;
|
||||
private String hostfwd = null;
|
||||
private String guestfwd = null;
|
||||
|
||||
//advanced
|
||||
public int disableacpi = 0;
|
||||
public int disablehpet = 0;
|
||||
public int disabletsc = 0;
|
||||
|
||||
public boolean enablleAvx = false;
|
||||
public String tbSize = "2048";
|
||||
|
||||
public String extra_params;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public StartVM(Context context) throws Exception {
|
||||
|
||||
name = Config.machinename;
|
||||
base_dir = Config.getBasefileDir();
|
||||
save_dir = Config.getMachineDir() + name;
|
||||
save_state_name = save_dir + "/" + Config.state_filename;
|
||||
hda_img_path = Config.hda_path;
|
||||
|
||||
extra_params = Config.extra_params;
|
||||
extra_params += " ";
|
||||
extra_params += MainSettingsManager.getCustomParams(MainActivity.activity);
|
||||
|
||||
if (MainSettingsManager.getSharedFolder(MainActivity.activity) && SDK_INT < 33)
|
||||
shared_folder_path = Config.sharedFolder;
|
||||
//extra_params = Config.extra_params;
|
||||
this.context = context;
|
||||
if (Objects.equals(MainSettingsManager.getArch(MainActivity.activity), "ARM")) {
|
||||
this.libqemu = FileUtils.getNativeLibDir(context) + "/libqemu-system-arm.so";
|
||||
File libFile = new File(libqemu);
|
||||
if (!libFile.exists()) {
|
||||
this.libqemu = FileUtils.getNativeLibDir(context) + "/libqemu-system-aarch64.so";
|
||||
libFile = new File(libqemu);
|
||||
}
|
||||
this.arch = "arm";
|
||||
this.machine_type = "virt";
|
||||
this.disablehpet = 0;
|
||||
this.disableacpi = 0;
|
||||
this.disabletsc = 0;
|
||||
this.cpu = "cortex-a57";
|
||||
} else if (Objects.equals(MainSettingsManager.getArch(MainActivity.activity), "X86_64")) {
|
||||
this.libqemu = FileUtils.getNativeLibDir(context) + "/libqemu-system-x86_64.so";
|
||||
this.arch = "x86_64";
|
||||
this.machine_type = "pc";
|
||||
this.cpu = MainSettingsManager.getCpu(MainActivity.activity);
|
||||
}
|
||||
bootdevice = MainSettingsManager.getBoot(MainActivity.activity);
|
||||
this.sound_card = MainSettingsManager.getSoundCard(MainActivity.activity);
|
||||
this.cpuNum = MainSettingsManager.getCpuNum(MainActivity.activity);
|
||||
|
||||
this.vnc_allow_external = 0;
|
||||
|
||||
this.enablleAvx = MainSettingsManager.getAvx(MainActivity.activity);
|
||||
|
||||
this.tbSize = MainSettingsManager.getTbSize(MainActivity.activity);
|
||||
|
||||
if (MainSettingsManager.getKvm(MainActivity.activity)) {
|
||||
this.enablekvm = 1;
|
||||
this.cpu = "host";
|
||||
this.enable_mttcg = 0;
|
||||
} else {
|
||||
if (MainSettingsManager.getMTTCG(MainActivity.activity)) {
|
||||
this.enable_mttcg = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (MainSettingsManager.getUsbTablet(MainActivity.activity))
|
||||
this.mouse = "usb-tablet";
|
||||
else
|
||||
this.mouse = "ps2";
|
||||
|
||||
if (new File(AppConfig.datadirpath(MainActivity.activity) + "/drive.iso").exists())
|
||||
cd_iso_path = AppConfig.maindirpath + "/drive.iso";
|
||||
else
|
||||
cd_iso_path = null;
|
||||
|
||||
if (new File(AppConfig.datadirpath(MainActivity.activity) + "/hdd1.qcow2").exists())
|
||||
hdc_img_path = AppConfig.maindirpath + "/hdd1.qcow2";
|
||||
else
|
||||
hdc_img_path = null;
|
||||
|
||||
if (new File(AppConfig.datadirpath(MainActivity.activity) + "/hdd2.qcow2").exists())
|
||||
hdd_img_path = AppConfig.maindirpath + "/hdd2.qcow2";
|
||||
else
|
||||
hdd_img_path = null;
|
||||
}
|
||||
|
||||
public static void onVMResolutionChanged(int width, int height) {
|
||||
|
||||
if (MainSDLActivity.mIsSurfaceReady)
|
||||
MainSDLActivity.onVMResolutionChanged(width, height);
|
||||
}
|
||||
|
||||
public void print(String[] params) {
|
||||
VectrasStatus.logInfo("Params:");
|
||||
Log.d(TAG, "Params:");
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
VectrasStatus.logInfo(i + ": " + params[i]);
|
||||
Log.d(TAG, i + ": " + params[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String startvm() {
|
||||
|
||||
String res = null;
|
||||
try {
|
||||
prepareParams();
|
||||
} catch (Exception ex) {
|
||||
UIUtils.toastLong(context, ex.getMessage());
|
||||
return res;
|
||||
}
|
||||
|
||||
//set the exit code
|
||||
MainSettingsManager.setExitCode(context, 2);
|
||||
|
||||
try {
|
||||
res = start(Config.storagedir, this.base_dir, this.libqemu, Config.SDLHintScale, params, this.paused, this.save_state_name);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Log.e(TAG, "Vectras Exception: " + ex.toString());
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void prepareParams() throws Exception {
|
||||
|
||||
params = null;
|
||||
ArrayList<String> paramsList = new ArrayList<String>();
|
||||
|
||||
paramsList.add(libqemu);
|
||||
|
||||
addUIOptions(paramsList);
|
||||
|
||||
addCpuBoardOptions(paramsList);
|
||||
|
||||
addDrives(paramsList);
|
||||
|
||||
addRemovableDrives(paramsList);
|
||||
|
||||
addBootOptions(paramsList);
|
||||
|
||||
addGraphicsOptions(paramsList);
|
||||
|
||||
addAudioOptions(paramsList);
|
||||
|
||||
addNetworkOptions(paramsList);
|
||||
|
||||
addAdvancedOptions(paramsList);
|
||||
|
||||
addGenericOptions(paramsList);
|
||||
|
||||
addStateOptions(paramsList);
|
||||
|
||||
params = (String[]) paramsList.toArray(new String[paramsList.size()]);
|
||||
|
||||
print(params);
|
||||
|
||||
}
|
||||
|
||||
private void addStateOptions(ArrayList<String> paramsList) {
|
||||
if (paused == 1 && this.save_state_name != null && !save_state_name.equals("")) {
|
||||
int fd_tmp = FileUtils.get_fd(context, save_state_name);
|
||||
if (fd_tmp < 0) {
|
||||
Log.e(TAG, "Error while getting fd for: " + save_state_name);
|
||||
} else {
|
||||
//Log.i(TAG, "Got new fd "+fd_tmp + " for: " +save_state_name);
|
||||
paramsList.add("-incoming");
|
||||
paramsList.add("fd:" + fd_tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addUIOptions(ArrayList<String> paramsList) {
|
||||
if (enablevnc != 0) {
|
||||
Log.v(TAG, "Enable VNC server");
|
||||
paramsList.add("-vnc");
|
||||
|
||||
if (vnc_allow_external != 0) {
|
||||
//TODO: Allow connections from External
|
||||
// Use with x509 auth and TLS for encryption
|
||||
paramsList.add(":1");
|
||||
} else {
|
||||
// Allow connections only from localhost using localsocket without a password
|
||||
//paramsList.add(Config.defaultVNCHost+":" + Config.defaultVNCPort);
|
||||
String qmpParams = "unix:";
|
||||
qmpParams += Config.getLocalVNCSocketPath();
|
||||
paramsList.add(qmpParams);
|
||||
}
|
||||
//Allow monitor console only for VNC,
|
||||
// SDL for android doesn't support more
|
||||
// than 1 window
|
||||
paramsList.add("-monitor");
|
||||
paramsList.add("vc");
|
||||
|
||||
} else if (enablespice != 0) {
|
||||
//Not working right now
|
||||
Log.v(TAG, "Enable SPICE server");
|
||||
paramsList.add("-spice");
|
||||
String spiceParams = "port=5902";
|
||||
|
||||
if (vnc_allow_external != 0 && vnc_passwd != null) {
|
||||
spiceParams += ",password=";
|
||||
spiceParams += vnc_passwd;
|
||||
} else
|
||||
spiceParams += ",addr=127.0.0.1"; // Allow only connections from localhost without password
|
||||
|
||||
spiceParams += ",disable-ticketing";
|
||||
//argv.add("-chardev");
|
||||
//argv.add("spicevm");
|
||||
} else {
|
||||
//SDL needs explicit keyboard layout
|
||||
Log.v(TAG, "Disabling VNC server, using SDL instead");
|
||||
if (keyboard_layout == null) {
|
||||
paramsList.add("-k");
|
||||
paramsList.add("en-us");
|
||||
}
|
||||
|
||||
//XXX: monitor, serial, and parallel display crashes cause SDL doesn't support more than 1 window
|
||||
paramsList.add("-monitor");
|
||||
paramsList.add("none");
|
||||
|
||||
paramsList.add("-serial");
|
||||
paramsList.add("none");
|
||||
|
||||
paramsList.add("-parallel");
|
||||
paramsList.add("none");
|
||||
}
|
||||
|
||||
if (keyboard_layout != null) {
|
||||
paramsList.add("-k");
|
||||
paramsList.add(keyboard_layout);
|
||||
}
|
||||
|
||||
if (mouse != null && !mouse.equals("ps2")) {
|
||||
paramsList.add("-machine");
|
||||
paramsList.add("usb=on");
|
||||
paramsList.add("-device");
|
||||
paramsList.add(mouse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addAdvancedOptions(ArrayList<String> paramsList) {
|
||||
|
||||
if (disableacpi != 0) {
|
||||
paramsList.add("-no-acpi"); //disable ACPI
|
||||
}
|
||||
if (disablehpet != 0) {
|
||||
paramsList.add("-no-hpet"); // disable HPET
|
||||
}
|
||||
|
||||
//TODO:Extra options
|
||||
if (extra_params != null && !extra_params.trim().equals("")) {
|
||||
String[] paramsTmp = extra_params.split(" ");
|
||||
paramsList.addAll(Arrays.asList(paramsTmp));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addAudioOptions(ArrayList<String> paramsList) {
|
||||
|
||||
if (sound_card != null && !sound_card.equals("None") && enablevnc != 1) {
|
||||
paramsList.add("-soundhw");
|
||||
paramsList.add(sound_card);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addGenericOptions(ArrayList<String> paramsList) {
|
||||
|
||||
paramsList.add("-L");
|
||||
paramsList.add(base_dir);
|
||||
|
||||
//XXX: Snapshots not working currently, use migrate/incoming instead
|
||||
if (snapshot_name != null && !snapshot_name.equals("")) {
|
||||
paramsList.add("-loadvm");
|
||||
paramsList.add(snapshot_name);
|
||||
}
|
||||
|
||||
if (enableqmp != 0) {
|
||||
|
||||
paramsList.add("-qmp");
|
||||
|
||||
if (qmp_allow_external != 0) {
|
||||
String qmpParams = "tcp:";
|
||||
qmpParams += (":" + this.qmp_port);
|
||||
qmpParams += ",server,nowait";
|
||||
paramsList.add(qmpParams);
|
||||
} else {
|
||||
//Specify a unix local domain as localhost to limit to local connections only
|
||||
String qmpParams = "unix:";
|
||||
qmpParams += Config.getLocalQMPSocketPath();
|
||||
qmpParams += ",server,nowait";
|
||||
paramsList.add(qmpParams);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Enable Tracing log
|
||||
// argv.add("-D");
|
||||
// argv.add("/sdcard/vectras/log.txt");
|
||||
// argv.add("--trace");
|
||||
// argv.add("events=/sdcard/vectras/tmp/events");
|
||||
// argv.add("--trace");
|
||||
// argv.add("file=/sdcard/vectras/tmp/trace");
|
||||
|
||||
// paramsList.add("-tb-size");
|
||||
// paramsList.add("32M"); //Don't increase it crashes
|
||||
|
||||
paramsList.add("-overcommit");
|
||||
paramsList.add("mem-lock=off");
|
||||
|
||||
paramsList.add("-rtc");
|
||||
paramsList.add("base=localtime");
|
||||
|
||||
paramsList.add("-nodefaults");
|
||||
|
||||
|
||||
//XXX: Usb redir not working under User mode
|
||||
//Redirect ports (SSH)
|
||||
// argv.add("-redir");
|
||||
// argv.add("5555::22");
|
||||
|
||||
}
|
||||
|
||||
private void addCpuBoardOptions(ArrayList<String> paramsList) {
|
||||
|
||||
//XXX: SMP is not working correctly for some guest OSes
|
||||
//so we enable multi core only under KVM
|
||||
// anyway regular emulation is not gaining any benefit unless mttcg is enabled but that
|
||||
// doesn't work for x86 guests yet
|
||||
if (this.cpuNum > 1 &&
|
||||
(enablekvm == 1 || enable_mttcg == 1 || !Config.enableSMPOnlyOnKVM)) {
|
||||
paramsList.add("-smp");
|
||||
paramsList.add("sockets=" + "1" + ",cores=" + this.cpuNum + ",threads=2");
|
||||
}
|
||||
|
||||
if (machine_type != null && !machine_type.equals("Default")) {
|
||||
paramsList.add("-M");
|
||||
paramsList.add(machine_type);
|
||||
}
|
||||
|
||||
//FIXME: something is wrong with quoting that doesn't let sparc qemu find the cpu def
|
||||
// for now we remove the cpu drop downlist items for sparc
|
||||
if (this.cpu != null && this.cpu.contains(" "))
|
||||
cpu = "'" + cpu + "'"; // XXX: needed for sparc cpu names
|
||||
|
||||
//XXX: we disable tsc feature for x86 since some guests are kernel panicking
|
||||
// if the cpu has not specified by user we use the internal qemu32/64
|
||||
if (disabletsc == 1 && (arch.equals("x86") || arch.equals("x86_64"))) {
|
||||
if (cpu == null || cpu.equals("Default")) {
|
||||
if (arch.equals("x86"))
|
||||
cpu = "qemu32";
|
||||
else if (arch.equals("x86_64"))
|
||||
cpu = "qemu64";
|
||||
}
|
||||
cpu += ",-tsc";
|
||||
}
|
||||
|
||||
if (this.cpu != null && !cpu.equals("Default")) {
|
||||
paramsList.add("-cpu");
|
||||
String cpuParams = cpu;
|
||||
if (enablleAvx)
|
||||
cpuParams += ",+avx";
|
||||
paramsList.add(cpuParams);
|
||||
|
||||
}
|
||||
|
||||
paramsList.add("-m");
|
||||
paramsList.add(RamInfo.vectrasMemory() + "");
|
||||
|
||||
|
||||
if (enablekvm != 0) {
|
||||
paramsList.add("-enable-kvm");
|
||||
} else if (this.enable_mttcg != 0 && Machine.isHost64Bit()) {
|
||||
//XXX: we should only do this for 64bit hosts
|
||||
paramsList.add("-accel");
|
||||
String tcgParams = "tcg";
|
||||
if (cpuNum > 1)
|
||||
tcgParams += ",thread=multi";
|
||||
else
|
||||
tcgParams += ",thread=single";
|
||||
tcgParams += ",tb-size=" + tbSize;
|
||||
paramsList.add(tcgParams);
|
||||
//#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addNetworkOptions(ArrayList<String> paramsList) throws Exception {
|
||||
|
||||
if (this.net_cfg != null) {
|
||||
paramsList.add("-net");
|
||||
if (net_cfg.equals("user")) {
|
||||
String netParams = net_cfg;
|
||||
if (hostfwd != null) {
|
||||
|
||||
//hostfwd=[tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport{,hostfwd=...}
|
||||
// example forward ssh from guest port 2222 to guest port 22:
|
||||
// hostfwd=tcp::2222-:22
|
||||
if (hostfwd.startsWith("hostfwd")) {
|
||||
throw new Exception("Invalid format for Host Forward, should be: tcp:hostport1:guestport1,udp:hostport2:questport2,...");
|
||||
}
|
||||
String[] hostfwdparams = hostfwd.split(",");
|
||||
for (int i = 0; i < hostfwdparams.length; i++) {
|
||||
netParams += ",";
|
||||
String[] hostfwdparam = hostfwdparams[i].split(":");
|
||||
netParams += ("hostfwd=" + hostfwdparam[0] + "::" + hostfwdparam[1] + "-:" + hostfwdparam[2]);
|
||||
}
|
||||
}
|
||||
if (guestfwd != null) {
|
||||
netParams += ",";
|
||||
netParams += guestfwd;
|
||||
}
|
||||
paramsList.add(netParams);
|
||||
} else if (net_cfg.equals("tap")) {
|
||||
paramsList.add("tap,vlan=0,ifname=tap0,script=no");
|
||||
} else if (net_cfg.equals("none")) {
|
||||
paramsList.add("none");
|
||||
} else {
|
||||
//Unknown interface
|
||||
paramsList.add("none");
|
||||
}
|
||||
}
|
||||
|
||||
if (nic_card != null) {
|
||||
paramsList.add("-net");
|
||||
String nicParams = "nic";
|
||||
if (net_cfg.equals("tap"))
|
||||
nicParams += ",vlan=0";
|
||||
if (!nic_card.equals("Default"))
|
||||
nicParams += (",model=" + nic_card);
|
||||
paramsList.add(nicParams);
|
||||
}
|
||||
}
|
||||
|
||||
private void addGraphicsOptions(ArrayList<String> paramsList) {
|
||||
if (vga_type != null) {
|
||||
if (vga_type.equals("Default")) {
|
||||
//do nothing
|
||||
} else if (vga_type.equals("virtio-gpu-pci")) {
|
||||
paramsList.add("-device");
|
||||
paramsList.add(vga_type);
|
||||
} else if (vga_type.equals("nographic")) {
|
||||
paramsList.add("-nographic");
|
||||
} else {
|
||||
paramsList.add("-vga");
|
||||
paramsList.add(vga_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void addBootOptions(ArrayList<String> paramsList) {
|
||||
if (this.bootdevice != null) {
|
||||
paramsList.add("-boot");
|
||||
paramsList.add(bootdevice);
|
||||
}
|
||||
|
||||
if (this.kernel != null && !this.kernel.equals("")) {
|
||||
paramsList.add("-kernel");
|
||||
paramsList.add(this.kernel);
|
||||
}
|
||||
|
||||
if (initrd != null && !initrd.equals("")) {
|
||||
paramsList.add("-initrd");
|
||||
paramsList.add(initrd);
|
||||
}
|
||||
|
||||
if (append != null && !append.equals("")) {
|
||||
paramsList.add("-append");
|
||||
paramsList.add(append);
|
||||
}
|
||||
}
|
||||
|
||||
public void addDrives(ArrayList<String> paramsList) {
|
||||
if (hda_img_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=0";
|
||||
if (Config.enable_hd_if) {
|
||||
param += ",if=";
|
||||
param += Config.hd_if_type;
|
||||
}
|
||||
param += ",media=disk";
|
||||
if (!hda_img_path.equals("")) {
|
||||
param += ",file=" + hda_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
if (hdb_img_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=1";
|
||||
if (Config.enable_hd_if) {
|
||||
param += ",if=";
|
||||
param += Config.hd_if_type;
|
||||
}
|
||||
param += ",media=disk";
|
||||
if (!hdb_img_path.equals("")) {
|
||||
param += ",file=" + hdb_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
if (hdc_img_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=2";
|
||||
if (Config.enable_hd_if) {
|
||||
param += ",if=";
|
||||
param += Config.hd_if_type;
|
||||
}
|
||||
param += ",media=disk";
|
||||
if (!hdc_img_path.equals("")) {
|
||||
param += ",file=" + hdc_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
if (hdd_img_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=3";
|
||||
if (Config.enable_hd_if) {
|
||||
param += ",if=";
|
||||
param += Config.hd_if_type;
|
||||
}
|
||||
param += ",media=disk";
|
||||
if (!hdd_img_path.equals("")) {
|
||||
param += ",file=" + hdd_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
} else if (shared_folder_path != null) {
|
||||
//XXX; We use hdd to mount any virtual fat drives
|
||||
paramsList.add("-drive"); //empty
|
||||
String driveParams = "index=3";
|
||||
driveParams += ",media=disk";
|
||||
if (Config.enable_hd_if) {
|
||||
driveParams += ",if=";
|
||||
driveParams += Config.hd_if_type;
|
||||
}
|
||||
|
||||
driveParams += ",format=raw";
|
||||
driveParams += ",file=fat:";
|
||||
driveParams += "rw:"; //Always Read/Write
|
||||
driveParams += shared_folder_path;
|
||||
paramsList.add(driveParams);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addRemovableDrives(ArrayList<String> paramsList) {
|
||||
|
||||
if (cd_iso_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=2";
|
||||
if (Config.enable_hd_if) {
|
||||
param += ",if=";
|
||||
param += Config.hd_if_type;
|
||||
}
|
||||
param += ",media=cdrom";
|
||||
if (!cd_iso_path.equals("")) {
|
||||
param += ",file=" + cd_iso_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
if (Config.enableEmulatedFloppy && fda_img_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=0,if=floppy";
|
||||
if (!fda_img_path.equals("")) {
|
||||
param += ",file=" + fda_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
if (Config.enableEmulatedFloppy && fdb_img_path != null) {
|
||||
paramsList.add("-drive"); //empty
|
||||
String param = "index=1,if=floppy";
|
||||
if (!fdb_img_path.equals("")) {
|
||||
param += ",file=" + fdb_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
if (Config.enableEmulatedSDCard && sd_img_path != null) {
|
||||
paramsList.add("-device");
|
||||
paramsList.add("sd-card,drive=sd0,bus=sd-bus");
|
||||
paramsList.add("-drive");
|
||||
String param = "if=none,id=sd0";
|
||||
if (!sd_img_path.equals("")) {
|
||||
param += ",file=" + sd_img_path;
|
||||
}
|
||||
paramsList.add(param);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//JNI Methods
|
||||
public native String start(String storage_dir, String base_dir, String lib_path, int sdl_scale_hint, Object[] params, int paused, String save_state_name);
|
||||
|
||||
public native String stop(int restart);
|
||||
|
||||
public native void setsdlrefreshrate(int value);
|
||||
|
||||
public native void setvncrefreshrate(int value);
|
||||
|
||||
public native int getsdlrefreshrate();
|
||||
|
||||
public native int getvncrefreshrate();
|
||||
|
||||
private native int onmouse(int button, int action, int relative, float x, float y);
|
||||
|
||||
private native int setrelativemousemode(int relativemousemode);
|
||||
|
||||
protected void vncchangepassword(String vnc_passwd) {
|
||||
String res = QmpClient.sendCommand(QmpClient.changevncpasswd(vnc_passwd));
|
||||
String desc = null;
|
||||
if (res != null && !res.equals("")) {
|
||||
try {
|
||||
JSONObject resObj = new JSONObject(res);
|
||||
if (resObj != null && !resObj.equals("") && res.contains("error")) {
|
||||
String resInfo = resObj.getString("error");
|
||||
if (resInfo != null && !resInfo.equals("")) {
|
||||
JSONObject resInfoObj = new JSONObject(resInfo);
|
||||
desc = resInfoObj.getString("desc");
|
||||
UIUtils.toastLong(context, "Could not set VNC Password: " + desc);
|
||||
Log.e(TAG, desc);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String changedev(String dev, String dev_value) {
|
||||
QmpClient.sendCommand(QmpClient.changedev(dev, dev_value));
|
||||
String display_dev_value = FileUtils.getFullPathFromDocumentFilePath(dev_value);
|
||||
return "Changed device: " + dev + " to " + display_dev_value;
|
||||
}
|
||||
|
||||
protected String ejectdev(String dev) {
|
||||
QmpClient.sendCommand(QmpClient.ejectdev(dev));
|
||||
return "Ejected device: " + dev;
|
||||
}
|
||||
|
||||
public String startvm(Context context, int ui) {
|
||||
MainService.executor = this;
|
||||
Intent i = new Intent(Config.ACTION_START, null, context, MainService.class);
|
||||
Bundle b = new Bundle();
|
||||
// b.putString("machine_type", this.machine_type);
|
||||
b.putInt("ui", ui);
|
||||
i.putExtras(b);
|
||||
context.startService(i);
|
||||
Log.v(TAG, "start VM service");
|
||||
return "startVMService";
|
||||
|
||||
}
|
||||
|
||||
public void stopvm(final int restart) {
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doStopVM(restart);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void doStopVM(final int restart) {
|
||||
|
||||
if (restart == 0) {
|
||||
MainService.stopService();
|
||||
|
||||
//XXX: Wait till service goes down
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (restart != 0) {
|
||||
QmpClient.sendCommand(QmpClient.reset());
|
||||
} else {
|
||||
//XXX: Qmp command only halts the VM but doesn't exit
|
||||
// so we use force close
|
||||
// QmpClient.sendCommand(QmpClient.powerDown());
|
||||
stop(restart);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String savevm(String statename) {
|
||||
// Set to delete previous snapshots after vm resumed
|
||||
Log.v(TAG, "Save Snapshot");
|
||||
this.snapshot_name = statename;
|
||||
|
||||
String res = null;
|
||||
//TODO:
|
||||
//res = QmpClient.sendCommand(QmpClient.saveSnapshot());
|
||||
return res;
|
||||
}
|
||||
|
||||
public String resumevm() {
|
||||
// Set to delete previous snapshots after vm resumed
|
||||
Log.v(TAG, "Resume the VM");
|
||||
String res = startvm();
|
||||
Log.d(TAG, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void change_vnc_password() {
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
vncchangepassword(vnc_passwd);
|
||||
}
|
||||
});
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public String get_state() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void change_dev(final String dev, final String image_path) {
|
||||
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
String image_path_conv = FileUtils.convertDocumentFilePath(image_path);
|
||||
if (image_path_conv == null || image_path_conv.trim().equals("")) {
|
||||
StartVM.this.busy = true;
|
||||
String res = StartVM.this.ejectdev(dev);
|
||||
Log.d(TAG, res);
|
||||
StartVM.this.busy = false;
|
||||
} else if (FileUtils.fileValid(context, image_path_conv)) {
|
||||
StartVM.this.busy = true;
|
||||
String res = StartVM.this.changedev(dev, image_path_conv);
|
||||
Log.d(TAG, res);
|
||||
StartVM.this.busy = false;
|
||||
} else {
|
||||
Log.d(TAG, "File does not exist");
|
||||
}
|
||||
}
|
||||
});
|
||||
thread.setPriority(Thread.MIN_PRIORITY);
|
||||
thread.start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public int get_fd(String path) {
|
||||
int fd = FileUtils.get_fd(context, path);
|
||||
return fd;
|
||||
|
||||
}
|
||||
|
||||
public int close_fd(int fd) {
|
||||
int res = FileUtils.close_fd(fd);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
public void prepPaths() {
|
||||
File destDir = new File(save_dir);
|
||||
if (!destDir.exists()) {
|
||||
destDir.mkdirs();
|
||||
}
|
||||
|
||||
// Protect the paths from qemu thinking they contain a protocol in the string
|
||||
|
||||
this.hda_img_path = FileUtils.convertDocumentFilePath(this.hda_img_path);
|
||||
if (this.hda_img_path != null && hda_img_path.equals("")) {
|
||||
hda_img_path = null;
|
||||
}
|
||||
this.hdb_img_path = FileUtils.convertDocumentFilePath(this.hdb_img_path);
|
||||
if (this.hdb_img_path != null && hdb_img_path.equals("")) {
|
||||
hdb_img_path = null;
|
||||
}
|
||||
this.hdc_img_path = FileUtils.convertDocumentFilePath(this.hdc_img_path);
|
||||
if (this.hdc_img_path != null && hdc_img_path.equals("")) {
|
||||
hdc_img_path = null;
|
||||
}
|
||||
this.hdd_img_path = FileUtils.convertDocumentFilePath(this.hdd_img_path);
|
||||
if (this.hdd_img_path != null && hdd_img_path.equals("")) {
|
||||
hdd_img_path = null;
|
||||
}
|
||||
|
||||
// Removable disks
|
||||
this.cd_iso_path = FileUtils.convertDocumentFilePath(this.cd_iso_path);
|
||||
this.fda_img_path = FileUtils.convertDocumentFilePath(this.fda_img_path);
|
||||
|
||||
this.fdb_img_path = FileUtils.convertDocumentFilePath(this.fdb_img_path);
|
||||
this.sd_img_path = FileUtils.convertDocumentFilePath(this.sd_img_path);
|
||||
|
||||
this.kernel = FileUtils.convertDocumentFilePath(this.kernel);
|
||||
this.initrd = FileUtils.convertDocumentFilePath(this.initrd);
|
||||
}
|
||||
|
||||
public int setRelativeMouseMode(int relative) {
|
||||
return setrelativemousemode(relative);
|
||||
}
|
||||
|
||||
public int onVectrasMouse(int button, int action, int relative, float x, float y) {
|
||||
//XXX: Make sure that mouse motion is not triggering crashes in SDL while resizing
|
||||
if (!MainSDLActivity.mIsSurfaceReady || MainSDLActivity.isResizing) {
|
||||
// Log.w(TAG, "onVectrasMouse: Ignoring mouse event surface not ready");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//XXX: Check boundaries, perhaps not necessary since SDL is also doing the same thing
|
||||
if (relative == 1
|
||||
|| (x >= 0 && x <= MainSDLActivity.vm_width && y >= 0 && y <= MainSDLActivity.vm_height)
|
||||
|| (action == MotionEvent.ACTION_SCROLL)) {
|
||||
// Log.d(TAG, "onVectrasMouse: B: " + button + ", A: " + action + ", R: " + relative + ", X: " + x + ", Y: " + y);
|
||||
return onmouse(button, action, relative, x, y);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,271 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Max Kastanas 2012
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
package com.vectras.qemu.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.Uri;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import android.util.Log;
|
||||
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author dev
|
||||
*/
|
||||
public class FileInstaller {
|
||||
|
||||
public static void installFiles(Activity activity, boolean force) {
|
||||
|
||||
Log.v("Installer", "Installing files...");
|
||||
File tmpDir = new File(Config.getBasefileDir());
|
||||
if (!tmpDir.exists()) {
|
||||
tmpDir.mkdirs();
|
||||
}
|
||||
|
||||
File tmpDir1 = new File(Config.getMachineDir());
|
||||
if (!tmpDir1.exists()) {
|
||||
tmpDir1.mkdirs();
|
||||
}
|
||||
|
||||
|
||||
//Install base dir
|
||||
File dir = new File(Config.getBasefileDir());
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
//don't create again
|
||||
} else if (dir.exists() && !dir.isDirectory()) {
|
||||
Log.v("Installer", "Could not create Dir, file found: " + Config.getBasefileDir());
|
||||
return;
|
||||
} else if (!dir.exists()) {
|
||||
dir.mkdir();
|
||||
}
|
||||
|
||||
String destDir = Config.getBasefileDir();
|
||||
|
||||
//Get each file in assets under ./roms/ and install in SDCARD
|
||||
AssetManager am = activity.getResources().getAssets();
|
||||
String[] files = null;
|
||||
try {
|
||||
files = am.list("roms");
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(FileInstaller.class.getName()).log(Level.SEVERE, null, ex);
|
||||
Log.v("Installer", "Could not install files: " + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
//Log.v("Installer", "File: " + files[i]);
|
||||
String[] subfiles = null;
|
||||
try {
|
||||
subfiles = am.list("roms/" + files[i]);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(FileInstaller.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
if (subfiles != null && subfiles.length > 0) {
|
||||
//Install base dir
|
||||
File dir1 = new File(Config.getBasefileDir() + files[i]);
|
||||
if (dir1.exists() && dir1.isDirectory()) {
|
||||
//don't create again
|
||||
} else if (dir1.exists() && !dir1.isDirectory()) {
|
||||
Log.v("Installer", "Could not create Dir, file found: " + Config.getBasefileDir() + files[i]);
|
||||
return;
|
||||
} else if (!dir1.exists()) {
|
||||
dir1.mkdir();
|
||||
}
|
||||
for (int k = 0; k < subfiles.length; k++) {
|
||||
|
||||
File file = new File(destDir, files[i] + "/" + subfiles[k]);
|
||||
if(!file.exists() || force) {
|
||||
Log.v("Installer", "Installing file: " + file.getPath());
|
||||
installAssetFile(activity, files[i] + "/" + subfiles[k], destDir, "roms", null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
File file = new File(destDir, files[i]);
|
||||
if(!file.exists() || force) {
|
||||
Log.v("Installer", "Installing file: " + file.getPath());
|
||||
installAssetFile(activity, files[i], Config.getBasefileDir(), "roms", null);
|
||||
}
|
||||
}
|
||||
}
|
||||
// InputStream is = am.open(srcFile);
|
||||
|
||||
}
|
||||
|
||||
public static boolean installAssetFile(Activity activity, String srcFile,
|
||||
String destDir, String assetsDir, String destFile) {
|
||||
try {
|
||||
AssetManager am = activity.getResources().getAssets(); // get the local asset manager
|
||||
InputStream is = am.open(assetsDir + "/" + srcFile); // open the input stream for reading
|
||||
File destDirF = new File(destDir);
|
||||
if (!destDirF.exists()) {
|
||||
boolean res = destDirF.mkdirs();
|
||||
if(!res){
|
||||
UIUtils.toastShort(activity, "Could not create directory for image");
|
||||
}
|
||||
}
|
||||
|
||||
if(destFile==null)
|
||||
destFile=srcFile;
|
||||
OutputStream os = new FileOutputStream(destDir + "/" + destFile);
|
||||
byte[] buf = new byte[8092];
|
||||
int n;
|
||||
while ((n = is.read(buf)) > 0) {
|
||||
os.write(buf, 0, n);
|
||||
}
|
||||
os.close();
|
||||
is.close();
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Log.e("Installer", "failed to install file: " + destFile + ", Error:" + ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Uri installImageTemplateToSDCard(Activity activity, String srcFile,
|
||||
Uri destDir, String assetsDir, String destFile) {
|
||||
|
||||
DocumentFile destFileF = null;
|
||||
OutputStream os = null;
|
||||
InputStream is = null;
|
||||
Uri uri = null;
|
||||
|
||||
try {
|
||||
|
||||
DocumentFile dir = DocumentFile.fromTreeUri(activity, destDir);
|
||||
AssetManager am = activity.getResources().getAssets(); // get the local asset manager
|
||||
is = am.open(assetsDir + "/" + srcFile); // open the input stream for reading
|
||||
|
||||
if(destFile==null)
|
||||
destFile=srcFile;
|
||||
|
||||
//Create the file if doesn't exist
|
||||
destFileF = dir.findFile(destFile);
|
||||
if(destFileF == null) {
|
||||
destFileF = dir.createFile("application/octet-stream", destFile);
|
||||
}
|
||||
else {
|
||||
UIUtils.toastShort(activity, "File exists, choose another filename");
|
||||
return null;
|
||||
}
|
||||
|
||||
//Write to the dest
|
||||
os = activity.getContentResolver().openOutputStream(destFileF.getUri());
|
||||
//OutputStream os = new FileOutputStream(destDir + "/" + destFile);
|
||||
byte[] buf = new byte[8092];
|
||||
int n;
|
||||
while ((n = is.read(buf)) > 0) {
|
||||
os.write(buf, 0, n);
|
||||
}
|
||||
|
||||
//success
|
||||
uri = destFileF.getUri();
|
||||
|
||||
} catch (Exception ex) {
|
||||
Log.e("Installer", "failed to install file: " + destFile + ", Error:" + ex.getMessage());
|
||||
} finally {
|
||||
if(os!=null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(is!=null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
|
||||
public static String installImageTemplateToExternalStorage(Activity activity, String srcFile,
|
||||
String destDir, String assetsDir, String destFile) {
|
||||
|
||||
File file = new File(destDir, destFile);
|
||||
String filePath = null;
|
||||
OutputStream os = null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
|
||||
AssetManager am = activity.getResources().getAssets(); // get the local asset manager
|
||||
is = am.open(assetsDir + "/" + srcFile); // open the input stream for reading
|
||||
|
||||
if(destFile==null)
|
||||
destFile=srcFile;
|
||||
|
||||
//Create the file if doesn't exist
|
||||
if(!file.exists()){
|
||||
file.createNewFile();
|
||||
}
|
||||
else {
|
||||
UIUtils.toastShort(activity, "File exists, choose another filename");
|
||||
return null;
|
||||
}
|
||||
|
||||
//Write to the dest
|
||||
os = new FileOutputStream(file);
|
||||
|
||||
//OutputStream os = new FileOutputStream(destDir + "/" + destFile);
|
||||
byte[] buf = new byte[8092];
|
||||
int n;
|
||||
while ((n = is.read(buf)) > 0) {
|
||||
os.write(buf, 0, n);
|
||||
}
|
||||
|
||||
//success
|
||||
filePath = file.getAbsolutePath();
|
||||
|
||||
} catch (Exception ex) {
|
||||
Log.e("Installer", "failed to install file: " + destFile + ", Error:" + ex.getMessage());
|
||||
} finally {
|
||||
if(os!=null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(is!=null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,647 +0,0 @@
|
|||
/*
|
||||
Copyright (C) Max Kastanas 2012
|
||||
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
package com.vectras.qemu.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import android.text.Spannable;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
/**
|
||||
* @author dev
|
||||
*/
|
||||
public class FileUtils {
|
||||
private final static String TAG = "FileUtils";
|
||||
public static HashMap<Integer, FileInfo> fds = new HashMap<Integer, FileInfo>();
|
||||
|
||||
public static String getNativeLibDir(Context context) {
|
||||
return context.getApplicationInfo().nativeLibraryDir;
|
||||
}
|
||||
|
||||
public static String getFullPathFromDocumentFilePath(String filePath) {
|
||||
|
||||
filePath = filePath.replaceAll("%3A", "^3A");
|
||||
int index = filePath.lastIndexOf("^3A");
|
||||
if (index > 0)
|
||||
filePath = filePath.substring(index + 3);
|
||||
if (!filePath.startsWith("/"))
|
||||
filePath = "/" + filePath;
|
||||
|
||||
// filePath = filePath.replaceAll("%2F", "/");
|
||||
// filePath = filePath.replaceAll("\\^2F", "/");
|
||||
|
||||
//remove any spaces encoded by the ASF
|
||||
try {
|
||||
filePath = URLDecoder.decode(filePath, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public static String getFilenameFromPath(String filePath) {
|
||||
filePath = filePath.replaceAll("%2F", "/");
|
||||
filePath = filePath.replaceAll("%3A", "/");
|
||||
filePath = filePath.replaceAll("\\^2F", "/");
|
||||
filePath = filePath.replaceAll("\\^3A", "/");
|
||||
|
||||
|
||||
int index = filePath.lastIndexOf("/");
|
||||
if (index > 0)
|
||||
return filePath.substring(index + 1);
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public static String unconvertDocumentFilePath(String filePath) {
|
||||
if (filePath != null && filePath.startsWith("/content//")) {
|
||||
filePath = filePath.replace("/content//", "content://");
|
||||
filePath = filePath.replaceAll("\\^\\^\\^", "%");
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public static String convertDocumentFilePath(String filePath) {
|
||||
if (filePath != null && filePath.startsWith("content://")) {
|
||||
filePath = filePath.replace("content://", "/content//");
|
||||
filePath = filePath.replaceAll("%", "\\^\\^\\^");;
|
||||
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public static void saveFileContents(String filePath, String contents) {
|
||||
// TODO: we assume that the contents are of small size so we keep in an array
|
||||
byteArrayToFile(contents.getBytes(), new File(filePath));
|
||||
}
|
||||
|
||||
public static void byteArrayToFile(byte[] byteData, File filePath) {
|
||||
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(filePath);
|
||||
fos.write(byteData);
|
||||
fos.close();
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
System.out.println("FileNotFoundException : " + ex);
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("IOException : " + ioe);
|
||||
}
|
||||
|
||||
}
|
||||
public static InputStream getStreamFromFilePath(Context context, String importFilePath) throws FileNotFoundException {
|
||||
InputStream stream = null;
|
||||
if (importFilePath.startsWith("content://")) {
|
||||
Uri uri = Uri.parse(importFilePath);
|
||||
String mode = "rw";
|
||||
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, mode);
|
||||
return new FileInputStream(pfd.getFileDescriptor());
|
||||
} else {
|
||||
return new FileInputStream(importFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFileContents(String filePath) {
|
||||
|
||||
File file = new File(filePath);
|
||||
if(!file.exists())
|
||||
return "";
|
||||
StringBuilder builder = new StringBuilder("");
|
||||
try {
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
byte[] buff = new byte[32768];
|
||||
int bytesRead = 0;
|
||||
while ((bytesRead = stream.read(buff, 0, buff.length)) > 0) {
|
||||
builder.append(new String(buff, "UTF-8"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
String contents = builder.toString();
|
||||
return contents;
|
||||
}
|
||||
|
||||
public static void viewVectrasLog(final Activity activity) {
|
||||
|
||||
String contents = FileUtils.getFileContents(Config.logFilePath);
|
||||
|
||||
if (contents.length() > 50 * 1024)
|
||||
contents = contents.substring(0, 25 * 1024)
|
||||
+ "\n.....\n" +
|
||||
contents.substring(contents.length() - 25 * 1024);
|
||||
|
||||
final String finalContents = contents;
|
||||
final Spannable contentsFormatted = UIUtils.formatAndroidLog(contents);
|
||||
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (Config.viewLogInternally) {
|
||||
UIUtils.UIAlertLog(activity, "Vectras Log", contentsFormatted);
|
||||
} else {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_EDIT);
|
||||
File file = new File(Config.logFilePath);
|
||||
Uri uri = Uri.fromFile(file);
|
||||
intent.setDataAndType(uri, "text/plain");
|
||||
activity.startActivity(intent);
|
||||
} catch (Exception ex) {
|
||||
// UIUtils.toastShort(activity, "Could not find a Text Viewer on your device");
|
||||
UIUtils.UIAlertLog(activity, "Vectras Log", contentsFormatted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static boolean fileValid(Context context, String path) {
|
||||
|
||||
if (path == null || path.equals(""))
|
||||
return true;
|
||||
if (path.startsWith("content://") || path.startsWith("/content/")) {
|
||||
int fd = get_fd(context, path);
|
||||
if (fd <= 0)
|
||||
return false;
|
||||
} else {
|
||||
File file = new File(path);
|
||||
return file.exists();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: we should pass the modes from the backend and translate them
|
||||
// instead of blindly using "rw". ie ISOs should be read only.
|
||||
public static int get_fd(final Context context, String path) {
|
||||
synchronized (fds) {
|
||||
int fd = 0;
|
||||
if (path == null)
|
||||
return 0;
|
||||
|
||||
// Log.d(TAG, "Opening Filepath: " + path);
|
||||
if (path.startsWith("/content//") || path.startsWith("content://")) {
|
||||
String npath = unconvertDocumentFilePath(path);
|
||||
|
||||
//Is this needed?
|
||||
// FileInfo info = getExistingFd(npath);
|
||||
// if (info!=null) {
|
||||
// ParcelFileDescriptor pfd = info.pfd;
|
||||
// fd = pfd.getFd();
|
||||
// Log.d(TAG, "Retrieved hashed documentfile: " + npath + ", FD: " + fd);
|
||||
// return fd;
|
||||
// }
|
||||
|
||||
|
||||
// Log.d(TAG, "Opening unconverted: " + npath);
|
||||
try {
|
||||
Uri uri = Uri.parse(npath);
|
||||
String mode = "rw";
|
||||
if (path.toLowerCase().endsWith(".iso"))
|
||||
mode = "r";
|
||||
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, mode);
|
||||
fd = pfd.getFd();
|
||||
// Log.d(TAG, "Opening DocumentFile: " + npath + ", FD: " + fd);
|
||||
fds.put(fd, new FileInfo(path, npath, pfd));
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not open DocumentFile: " + npath + ", FD: " + fd);
|
||||
if(Config.debug)
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
//Is this needed?
|
||||
// FileInfo info = getExistingFd(path);
|
||||
// if (info!=null) {
|
||||
// ParcelFileDescriptor pfd = info.pfd;
|
||||
// fd = pfd.getFd();
|
||||
// Log.d(TAG, "Retrieved hashed file: " + path + ", FD: " + fd);
|
||||
// return fd;
|
||||
// }
|
||||
|
||||
try {
|
||||
int mode = ParcelFileDescriptor.MODE_READ_WRITE;
|
||||
if (path.toLowerCase().endsWith(".iso"))
|
||||
mode = ParcelFileDescriptor.MODE_READ_ONLY;
|
||||
|
||||
File file = new File(path);
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, mode);
|
||||
fd = pfd.getFd();
|
||||
fds.put(fd, new FileInfo(path, path, pfd));
|
||||
Log.d(TAG, "Opening File: " + path + ", FD: " + fd);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not open File: " + path + ", FD: " + fd);
|
||||
if(Config.debug)
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
private static FileInfo getExistingFd(String npath) {
|
||||
Set<Map.Entry<Integer, FileInfo>> fileInfoSet = fds.entrySet();
|
||||
Iterator<Map.Entry<Integer, FileInfo>> iter = fileInfoSet.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Integer, FileInfo> entry = iter.next();
|
||||
FileInfo fileInfo = entry.getValue();
|
||||
if (fileInfo.npath.equals(npath)) {
|
||||
return fileInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void close_fds() {
|
||||
synchronized (fds) {
|
||||
Integer[] fds = FileUtils.fds.keySet().toArray(new Integer[FileUtils.fds.keySet().size()]);
|
||||
for (int i = 0; i < fds.length; i++) {
|
||||
FileUtils.close_fd(fds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int close_fd(int fd) {
|
||||
if(!Config.closeFileDescriptors) {
|
||||
return 0;
|
||||
}
|
||||
synchronized (fds) {
|
||||
// Log.d(TAG, "Closing FD: " + fd);
|
||||
if (FileUtils.fds.containsKey(fd)) {
|
||||
|
||||
FileInfo info = FileUtils.fds.get(fd);
|
||||
|
||||
|
||||
try {
|
||||
|
||||
ParcelFileDescriptor pfd = info.pfd;
|
||||
try {
|
||||
pfd.getFileDescriptor().sync();
|
||||
} catch (IOException e) {
|
||||
if(Config.debug) {
|
||||
Log.w(TAG, "Syncing DocumentFile: " + info.path + ": " + fd + " : " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Log.d(TAG, "Closing DocumentFile: " + info.npath + ", FD: " + fd);
|
||||
pfd.close();
|
||||
FileUtils.fds.remove(fd);
|
||||
return 0; // success for Native side
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error Closing DocumentFile: " + info.path + ": " + fd + " : " + e);
|
||||
if(Config.debug)
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
ParcelFileDescriptor pfd = null;
|
||||
String path = "unknown";
|
||||
try {
|
||||
|
||||
//xxx: check the hash
|
||||
FileInfo info = FileUtils.fds.get(fd);
|
||||
if(info!=null) {
|
||||
pfd = info.pfd;
|
||||
path = info.path;
|
||||
// Log.d(TAG, "Closing hashe File FD: " + fd + ": " + info.path);
|
||||
}
|
||||
|
||||
//xxx: else get a new parcel
|
||||
if(pfd == null)
|
||||
pfd = ParcelFileDescriptor.fromFd(fd);
|
||||
|
||||
// Log.d(TAG, "Closing File FD: " + fd);
|
||||
try {
|
||||
pfd.getFileDescriptor().sync();
|
||||
} catch (IOException e) {
|
||||
if(Config.debug) {
|
||||
Log.e(TAG, "Error Syncing File: " + path + ": " + fd + " : " + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
pfd.close();
|
||||
return 0;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error Closing File FD: " + path + ": " + fd + " : " + e);
|
||||
if(Config.debug)
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void startLogging() {
|
||||
|
||||
if (Config.logFilePath == null) {
|
||||
Log.e(TAG, "Log file is not setup");
|
||||
return;
|
||||
}
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
FileOutputStream os = null;
|
||||
File logFile = null;
|
||||
try {
|
||||
logFile = new File(Config.logFilePath);
|
||||
if (logFile.exists()) {
|
||||
logFile.delete();
|
||||
}
|
||||
logFile.createNewFile();
|
||||
Runtime.getRuntime().exec("logcat -c");
|
||||
Process process = Runtime.getRuntime().exec("logcat v main");
|
||||
os = new FileOutputStream(logFile);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
StringBuilder log = new StringBuilder("");
|
||||
String line = "";
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
log.setLength(0);
|
||||
log.append(line).append("\n");
|
||||
os.write(log.toString().getBytes("UTF-8"));
|
||||
os.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
t.setName("VectrasLogger");
|
||||
t.start();
|
||||
}
|
||||
|
||||
public static String LoadFile(Activity activity, String fileName, boolean loadFromRawFolder) throws IOException {
|
||||
// Create a InputStream to read the file into
|
||||
InputStream iS;
|
||||
if (loadFromRawFolder) {
|
||||
// get the resource id from the file name
|
||||
int rID = activity.getResources().getIdentifier(activity.getClass().getPackage().getName() + ":raw/" + fileName,
|
||||
null, null);
|
||||
// get the file as a stream
|
||||
iS = activity.getResources().openRawResource(rID);
|
||||
} else {
|
||||
// get the file as a stream
|
||||
iS = activity.getResources().getAssets().open(fileName);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream oS = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[iS.available()];
|
||||
int bytesRead = 0;
|
||||
while ((bytesRead = iS.read(buffer)) > 0) {
|
||||
oS.write(buffer);
|
||||
}
|
||||
oS.close();
|
||||
iS.close();
|
||||
|
||||
// return the output stream as a String
|
||||
return oS.toString();
|
||||
}
|
||||
|
||||
public static String getExtensionFromFilename(String fileName) {
|
||||
if (fileName == null)
|
||||
return "";
|
||||
|
||||
int index = fileName.lastIndexOf(".");
|
||||
if (index >= 0) {
|
||||
return fileName.substring(index + 1);
|
||||
} else
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int getIconForFile(String file) {
|
||||
// file = file.toLowerCase();
|
||||
// String ext = FileUtils.getExtensionFromFilename(file).toLowerCase();
|
||||
//
|
||||
// if(ext.equals("img") || ext.equals("qcow")
|
||||
// || ext.equals("qcow2") || ext.equals("vmdk") || ext.equals("vdi") || ext.equals("cow")
|
||||
// || ext.equals("dmg") || ext.equals("bochs") || ext.equals("vpc")
|
||||
// || ext.equals("vhd") || ext.equals("fs"))
|
||||
// return R.drawable.harddisk;
|
||||
// else if(ext.equals("iso"))
|
||||
// return R.drawable.cd;
|
||||
// else if(ext.equals("ima"))
|
||||
// return R.drawable.floppy;
|
||||
// else if(ext.equals("csv"))
|
||||
// return R.drawable.importvms;
|
||||
// else if(file.contains("kernel") || file.contains("vmlinuz") || file.contains("initrd"))
|
||||
// return R.drawable.sysfile;
|
||||
// else
|
||||
// return R.drawable.close;
|
||||
return R.mipmap.ic_launcher;
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static Uri saveLogFileSDCard(Activity activity,
|
||||
Uri destDir) {
|
||||
|
||||
DocumentFile destFileF = null;
|
||||
OutputStream os = null;
|
||||
Uri uri = null;
|
||||
|
||||
try {
|
||||
String logFileContents = getFileContents(Config.logFilePath);
|
||||
DocumentFile dir = DocumentFile.fromTreeUri(activity, destDir);
|
||||
|
||||
//Create the file if doesn't exist
|
||||
destFileF = dir.findFile(Config.destLogFilename);
|
||||
if(destFileF == null) {
|
||||
destFileF = dir.createFile(MimeTypeMap.getSingleton().getMimeTypeFromExtension("txt"), Config.destLogFilename);
|
||||
}
|
||||
|
||||
//Write to the dest
|
||||
os = activity.getContentResolver().openOutputStream(destFileF.getUri());
|
||||
os.write(logFileContents.getBytes());
|
||||
|
||||
//success
|
||||
uri = destFileF.getUri();
|
||||
|
||||
} catch (Exception ex) {
|
||||
UIUtils.toastShort(activity, "Failed to save log file: " + ex.getMessage());
|
||||
} finally {
|
||||
if(os!=null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
public static String saveLogFileLegacy(Activity activity,
|
||||
String destLogFilePath) {
|
||||
|
||||
String filePath = null;
|
||||
File destFileF = new File(destLogFilePath, Config.destLogFilename);
|
||||
|
||||
try {
|
||||
String logFileContents = getFileContents(Config.logFilePath);
|
||||
FileUtils.saveFileContents(destFileF.getAbsolutePath(), logFileContents);
|
||||
|
||||
//success
|
||||
filePath = destFileF.getAbsolutePath();
|
||||
|
||||
} catch (Exception ex) {
|
||||
UIUtils.toastShort(activity, "Failed to save log file: " + destFileF.getAbsolutePath() + ", Error:" + ex.getMessage());
|
||||
} finally {
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
|
||||
|
||||
public static String getFileUriFromIntent(Activity activity, Intent data, boolean write) {
|
||||
if(data == null)
|
||||
return null;
|
||||
|
||||
Uri uri = data.getData();
|
||||
DocumentFile pickedFile = DocumentFile.fromSingleUri(activity, uri);
|
||||
String file = uri.toString();
|
||||
if (!file.contains("com.android.externalstorage.documents")) {
|
||||
UIUtils.showFileNotSupported(activity);
|
||||
return null;
|
||||
}
|
||||
activity.grantUriPermission(activity.getPackageName(), uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if(write)
|
||||
activity.grantUriPermission(activity.getPackageName(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
activity.grantUriPermission(activity.getPackageName(), uri, Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
||||
|
||||
int takeFlags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
if(write)
|
||||
takeFlags = takeFlags | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
|
||||
|
||||
activity.getContentResolver().takePersistableUriPermission(uri, takeFlags);
|
||||
return file;
|
||||
}
|
||||
|
||||
public static String getDirPathFromIntent(Activity activity, Intent data) {
|
||||
if(data == null)
|
||||
return null;
|
||||
Bundle b = data.getExtras();
|
||||
String file = b.getString("currDir");
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
public static String getFilePathFromIntent(Activity activity, Intent data) {
|
||||
if(data == null)
|
||||
return null;
|
||||
Bundle b = data.getExtras();
|
||||
String file = b.getString("file");
|
||||
return file;
|
||||
}
|
||||
|
||||
public static class FileInfo {
|
||||
public String path;
|
||||
public String npath;
|
||||
public ParcelFileDescriptor pfd;
|
||||
|
||||
public FileInfo(String path, String npath, ParcelFileDescriptor pfd) {
|
||||
this.npath = npath;
|
||||
this.path = path;
|
||||
this.pfd = pfd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void saveLogToFile(final Activity activity, final String logFileDestDir) {
|
||||
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
String displayName = null;
|
||||
if (logFileDestDir.startsWith("content://")) {
|
||||
Uri exportDirUri = Uri.parse(logFileDestDir);
|
||||
Uri fileCreatedUri = FileUtils.saveLogFileSDCard(activity,
|
||||
exportDirUri);
|
||||
displayName = FileUtils.getFullPathFromDocumentFilePath(fileCreatedUri.toString());
|
||||
} else {
|
||||
String filePath = FileUtils.saveLogFileLegacy(activity, logFileDestDir);
|
||||
displayName = filePath;
|
||||
}
|
||||
|
||||
if(displayName!=null){
|
||||
|
||||
UIUtils.toastShort(activity, "Logfile saved");
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
package com.vectras.qemu.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Machine {
|
||||
|
||||
public static final String EMPTY = "empty";
|
||||
public static String TAG = "Machine";
|
||||
|
||||
public static void promptPausedVM(final Activity activity) {
|
||||
|
||||
new AlertDialog.Builder(activity, R.style.MainDialogTheme).setCancelable(false).setTitle("Paused").setMessage("VM is now Paused tap OK to exit")
|
||||
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
Log.i(TAG, "VM Paused, Shutting Down");
|
||||
if (activity.getParent() != null) {
|
||||
activity.getParent().finish();
|
||||
} else {
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
if (MainActivity.vmexecutor != null) {
|
||||
MainActivity.vmexecutor.stopvm(0);
|
||||
}
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
|
||||
public static void onRestartVM(final Context context) {
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
if (MainActivity.vmexecutor != null) {
|
||||
Log.v(TAG, "Restarting the VM...");
|
||||
MainActivity.vmexecutor.stopvm(1);
|
||||
|
||||
MainActivity.vmStarted = true;
|
||||
if(Config.showToast)
|
||||
UIUtils.toastShort(context, "VM Reset");
|
||||
|
||||
} else {
|
||||
if(Config.showToast)
|
||||
UIUtils.toastShort(context, "VM Not Running");
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
|
||||
public static void pausedErrorVM(Activity activity, String errStr) {
|
||||
|
||||
errStr = errStr != null ? errStr : "Could not pause VM. View log for details";
|
||||
|
||||
new AlertDialog.Builder(activity, R.style.MainDialogTheme).setTitle("Error").setMessage(errStr)
|
||||
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
String command = QmpClient.cont();
|
||||
String msg = QmpClient.sendCommand(command);
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
public static void stopVM(final Activity activity) {
|
||||
|
||||
new AlertDialog.Builder(activity, R.style.MainDialogTheme).setTitle("Shutdown VM")
|
||||
.setMessage("To avoid any corrupt data make sure you "
|
||||
+ "have already shutdown the Operating system from within the VM. Continue?")
|
||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (activity.getParent() != null) {
|
||||
activity.getParent().finish();
|
||||
} else {
|
||||
activity.finish();
|
||||
}
|
||||
|
||||
if (MainActivity.vmexecutor != null) {
|
||||
MainActivity.vmexecutor.stopvm(0);
|
||||
}
|
||||
}
|
||||
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
public static MainActivity.VMStatus checkSaveVMStatus(final Activity activity) {
|
||||
String pause_state = "";
|
||||
if (MainActivity.vmexecutor != null) {
|
||||
|
||||
String command = QmpClient.query_migrate();
|
||||
String res = QmpClient.sendCommand(command);
|
||||
|
||||
if (res != null && !res.equals("")) {
|
||||
//Log.d(TAG, "Migrate status: " + res);
|
||||
try {
|
||||
JSONObject resObj = new JSONObject(res);
|
||||
String resInfo = resObj.getString("return");
|
||||
JSONObject resInfoObj = new JSONObject(resInfo);
|
||||
pause_state = resInfoObj.getString("status");
|
||||
} catch (JSONException e) {
|
||||
if (Config.debug)
|
||||
Log.e(TAG,e.getMessage());
|
||||
//e.printStackTrace();
|
||||
}
|
||||
if (pause_state != null && pause_state.toUpperCase().equals("FAILED")) {
|
||||
Log.e(TAG, "Error: " + res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pause_state.toUpperCase().equals("ACTIVE")) {
|
||||
return MainActivity.VMStatus.Saving;
|
||||
} else if (pause_state.toUpperCase().equals("COMPLETED")) {
|
||||
MainActivity.vmexecutor.paused = 1;
|
||||
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
promptPausedVM(activity);
|
||||
}
|
||||
}, 1000);
|
||||
return MainActivity.VMStatus.Completed;
|
||||
|
||||
} else if (pause_state.toUpperCase().equals("FAILED")) {
|
||||
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pausedErrorVM(activity, null);
|
||||
}
|
||||
}, 100);
|
||||
return MainActivity.VMStatus.Failed;
|
||||
}
|
||||
return MainActivity.VMStatus.Unknown;
|
||||
}
|
||||
|
||||
public static boolean isHostX86_64() {
|
||||
if(Build.SUPPORTED_64_BIT_ABIS != null)
|
||||
{
|
||||
for(int i=0; i< Build.SUPPORTED_64_BIT_ABIS.length ; i++)
|
||||
if(Build.SUPPORTED_64_BIT_ABIS[i].equals("x86_64"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHostX86() {
|
||||
if(Build.SUPPORTED_32_BIT_ABIS != null)
|
||||
{
|
||||
for(int i=0; i< Build.SUPPORTED_32_BIT_ABIS.length ; i++)
|
||||
if(Build.SUPPORTED_32_BIT_ABIS[i].equals("x86"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHostArm() {
|
||||
if(Build.SUPPORTED_32_BIT_ABIS != null)
|
||||
{
|
||||
for(int i=0; i< Build.SUPPORTED_32_BIT_ABIS.length ; i++)
|
||||
if(Build.SUPPORTED_32_BIT_ABIS[i].equals("armeabi-v7a"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHostArmv8() {
|
||||
if(Build.SUPPORTED_64_BIT_ABIS != null)
|
||||
{
|
||||
for(int i=0; i< Build.SUPPORTED_64_BIT_ABIS.length ; i++)
|
||||
if(Build.SUPPORTED_64_BIT_ABIS[i].equals("arm64-v8a"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHost64Bit() {
|
||||
return Build.SUPPORTED_64_BIT_ABIS!=null && Build.SUPPORTED_64_BIT_ABIS.length > 0 ;
|
||||
}
|
||||
|
||||
|
||||
public static void resetVM(final Activity activity) {
|
||||
|
||||
new AlertDialog.Builder(activity, R.style.MainDialogTheme).setTitle("Reset VM")
|
||||
.setMessage("To avoid any corrupt data make sure you "
|
||||
+ "have already shutdown the Operating system from within the VM. Continue?")
|
||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
Log.v(TAG, "VM is reset");
|
||||
Machine.onRestartVM(activity);
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
package com.vectras.qemu.utils;
|
||||
|
||||
import android.net.LocalSocket;
|
||||
import android.net.LocalSocketAddress;
|
||||
import android.util.Log;
|
||||
|
||||
import com.vectras.qemu.Config;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
|
||||
public class QmpClient {
|
||||
|
||||
private static final String TAG = "QmpClient";
|
||||
private static String requestCommandMode = "{ \"execute\": \"qmp_capabilities\" }";
|
||||
public static boolean allow_external = false;
|
||||
|
||||
public synchronized static String sendCommand(String command) {
|
||||
String response = null;
|
||||
int trial=0;
|
||||
Socket pingSocket = null;
|
||||
LocalSocket localSocket = null;
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
|
||||
try {
|
||||
if(allow_external) {
|
||||
pingSocket = new Socket(Config.QMPServer, Config.QMPPort);
|
||||
pingSocket.setSoTimeout(5000);
|
||||
out = new PrintWriter(pingSocket.getOutputStream(), true);
|
||||
in = new BufferedReader(new InputStreamReader(pingSocket.getInputStream()));
|
||||
} else {
|
||||
localSocket = new LocalSocket();
|
||||
String localQMPSocketPath = Config.getLocalQMPSocketPath();
|
||||
LocalSocketAddress localSocketAddr = new LocalSocketAddress(localQMPSocketPath, LocalSocketAddress.Namespace.FILESYSTEM);
|
||||
localSocket.connect(localSocketAddr);
|
||||
localSocket.setSoTimeout(5000);
|
||||
out = new PrintWriter(localSocket.getOutputStream(), true);
|
||||
in = new BufferedReader(new InputStreamReader(localSocket.getInputStream()));
|
||||
}
|
||||
|
||||
|
||||
sendRequest(out, QmpClient.requestCommandMode);
|
||||
while(true){
|
||||
response = getResponse(in);
|
||||
if(response == null || response.equals("") || trial <10)
|
||||
break;
|
||||
|
||||
Thread.sleep(1000);
|
||||
trial++;
|
||||
}
|
||||
|
||||
sendRequest(out, command);
|
||||
trial=0;
|
||||
while((response = getResponse(in)).equals("") && trial < 10){
|
||||
Thread.sleep(1000);
|
||||
trial++;
|
||||
}
|
||||
} catch (java.net.ConnectException e) {
|
||||
Log.w(TAG, "Could not connect to QMP: " + e);
|
||||
if(Config.debugQmp)
|
||||
e.printStackTrace();
|
||||
} catch(Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
Log.e(TAG, "Error while connecting to QMP: " + e);
|
||||
if(Config.debugQmp)
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null)
|
||||
out.close();
|
||||
try {
|
||||
if (in != null)
|
||||
in.close();
|
||||
if (pingSocket != null)
|
||||
pingSocket.close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private static void sendRequest(PrintWriter out, String request) {
|
||||
|
||||
if(Config.debugQmp)
|
||||
Log.i(TAG, "QMP request" + request);
|
||||
out.println(request);
|
||||
}
|
||||
|
||||
private static String getResponse(BufferedReader in) throws Exception {
|
||||
|
||||
String line;
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
|
||||
try {
|
||||
do {
|
||||
line = in.readLine();
|
||||
if (line != null) {
|
||||
if(Config.debugQmp)
|
||||
Log.i(TAG, "QMP response: " + line);
|
||||
JSONObject object = new JSONObject(line);
|
||||
String returnStr = null;
|
||||
String errStr = null;
|
||||
|
||||
try {
|
||||
if(line.contains("return"))
|
||||
returnStr = object.getString("return");
|
||||
} catch (Exception ex) {
|
||||
if(Config.debugQmp)
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
if (returnStr != null) {
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
if(line.contains("error"))
|
||||
errStr = object.getString("error");
|
||||
} catch (Exception ex) {
|
||||
if(Config.debugQmp)
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
|
||||
if (errStr != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} else
|
||||
break;
|
||||
} while (true);
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "Could not get Response: " + ex.getMessage());
|
||||
if(Config.debugQmp)
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static String getQueryMigrateResponse(BufferedReader in) throws Exception {
|
||||
|
||||
String line;
|
||||
StringBuilder stringBuilder = new StringBuilder("");
|
||||
|
||||
try {
|
||||
do {
|
||||
line = in.readLine();
|
||||
if (line != null) {
|
||||
if(Config.debugQmp)
|
||||
Log.i(TAG, "QMP query-migrate response: " + line);
|
||||
JSONObject object = new JSONObject(line);
|
||||
String returnStr = null;
|
||||
String errStr = null;
|
||||
|
||||
try {
|
||||
returnStr = object.getString("return");
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
|
||||
if (returnStr != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
errStr = object.getString("error");
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
|
||||
stringBuilder.append(line);
|
||||
stringBuilder.append("\n");
|
||||
|
||||
if (errStr != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} else
|
||||
break;
|
||||
} while (true);
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static String migrate(boolean block, boolean inc, String uri) {
|
||||
|
||||
// XXX: Detach should not be used via QMP according to docs
|
||||
// return "{\"execute\":\"migrate\",\"arguments\":{\"detach\":" + detach
|
||||
// + ",\"blk\":" + block + ",\"inc\":" + inc
|
||||
// + ",\"uri\":\"" + uri + "\"},\"id\":\"limbo\"}";
|
||||
|
||||
// its better not to use block (full disk copy) cause its slow (though
|
||||
// safer)
|
||||
// see qmp-commands.hx for more info
|
||||
return "{\"execute\":\"migrate\",\"arguments\":{\"blk\":" + block + ",\"inc\":" + inc + ",\"uri\":\"" + uri
|
||||
+ "\"},\"id\":\"limbo\"}";
|
||||
|
||||
}
|
||||
|
||||
public static String changevncpasswd(String passwd) {
|
||||
|
||||
return "{\"execute\": \"change\", \"arguments\": { \"device\": \"vnc\", \"target\": \"password\", \"arg\": \"" + passwd +"\" } }";
|
||||
|
||||
}
|
||||
|
||||
public static String ejectdev(String dev) {
|
||||
|
||||
return "{ \"execute\": \"eject\", \"arguments\": { \"device\": \""+ dev +"\" } }";
|
||||
|
||||
}
|
||||
|
||||
public static String changedev(String dev, String value) {
|
||||
|
||||
return "{ \"execute\": \"change\", \"arguments\": { \"device\": \""+dev+"\", \"target\": \"" + value + "\" } }";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String query_migrate() {
|
||||
return "{ \"execute\": \"query-migrate\" }";
|
||||
|
||||
}
|
||||
|
||||
public static String save_snapshot(String snapshot_name) {
|
||||
return "{\"execute\": \"snapshot-create\", \"arguments\": {\"name\": \""+ snapshot_name+"\"} }";
|
||||
|
||||
}
|
||||
|
||||
public static String query_snapshot() {
|
||||
return "{ \"execute\": \"query-snapshot-status\" }";
|
||||
|
||||
}
|
||||
|
||||
public static String stop() {
|
||||
return "{ \"execute\": \"stop\" }";
|
||||
|
||||
}
|
||||
|
||||
public static String cont() {
|
||||
return "{ \"execute\": \"cont\" }";
|
||||
|
||||
}
|
||||
|
||||
public static String powerDown() {
|
||||
return "{ \"execute\": \"system_powerdown\" }";
|
||||
|
||||
}
|
||||
|
||||
public static String reset() {
|
||||
return "{ \"execute\": \"system_reset\" }";
|
||||
|
||||
}
|
||||
|
||||
public static String getState() {
|
||||
return "{ \"execute\": \"query-status\" }";
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package com.vectras.qemu.utils;
|
||||
|
||||
import static android.content.Context.ACTIVITY_SERVICE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
|
||||
public class RamInfo {
|
||||
public static Activity activity;
|
||||
|
||||
public static int safeLongToInt(long l) {
|
||||
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
|
||||
}
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
public static int vectrasMemory() {
|
||||
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
|
||||
ActivityManager activityManager = (ActivityManager) activity.getSystemService(ACTIVITY_SERVICE);
|
||||
activityManager.getMemoryInfo(mi);
|
||||
long freeMem = mi.availMem / 1048576L;
|
||||
long totalMem = mi.totalMem / 1048576L;
|
||||
long usedMem = totalMem - freeMem;
|
||||
int freeRamInt = safeLongToInt(freeMem);
|
||||
int totalRamInt = safeLongToInt(totalMem);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
if (prefs.getBoolean("customMemory", false)) {
|
||||
return Integer.parseInt(prefs.getString("memory", String.valueOf(256)));
|
||||
} else {
|
||||
return freeRamInt - 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue