mirror of
https://github.com/xoureldeen/Vectras-VM-Android.git
synced 2026-04-29 23:09:48 +00:00
v2.9.5.7-3dfx
- Fixed VNC Server could fail to connect from another device. - Added no more update prompts for an updated version. - Fixed missing package check could give wrong results for 32bit only devices. - Fixed VM not being created when ignoring warnings. - Termux:X11 startup command now only runs for Android 13 and below. - Added check if cache folder was created successfully when running VM. - Added VNC Server running notification dialog after successful VM launch. - New Home interface. - Rom store has been integrated in Home. - New System monitor. - Updated update notification dialog interface. - New update checker. - Reduced time on startup screen. - Fixed issue with virtual machine list data fixer.
This commit is contained in:
parent
d351766486
commit
149e3c29ea
81 changed files with 4108 additions and 1093 deletions
|
|
@ -135,10 +135,6 @@ public class AboutActivity extends AppCompatActivity implements View.OnClickList
|
|||
} else {
|
||||
Log.d("TAG", "The interstitial ad wasn't ready yet.");
|
||||
}
|
||||
|
||||
//TextView textversionname = findViewById(R.id.versionname);
|
||||
//PackageInfo pinfo = MainActivity.activity.getAppInfo(getApplicationContext());
|
||||
//textversionname.setText(pinfo.versionName);
|
||||
|
||||
RecyclerView recyclerView = findViewById(R.id.github_users_recycler_view);
|
||||
String[] usernames = {"vectras-team", "xoureldeen", "ahmedbarakat2007", "anbui2004"};
|
||||
|
|
|
|||
|
|
@ -76,10 +76,14 @@ public class AppConfig {
|
|||
public static String pendingCommand = "";
|
||||
|
||||
public static String neededPkgs = "aria2 tar dwm xfce4-terminal libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
|
||||
" libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev rdma-core" +
|
||||
" libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev rdma-core" +
|
||||
" libusb ncurses-libs curl libnfs sdl2 gtk+3.0 fuse libpulse libseccomp jack pipewire liburing" +
|
||||
" mesa-dri-gallium mesa-vulkan-swrast vulkan-loader mesa-utils mesa-egl mesa-gbm mesa-vulkan-ati mesa-vulkan-broadcom mesa-vulkan-freedreno mesa-vulkan-panfrost";
|
||||
|
||||
public static String neededPkgs32bit = "aria2 tar dwm xfce4-terminal libslirp libslirp-dev pulseaudio-dev glib-dev pixman-dev zlib-dev spice-dev" +
|
||||
" libusbredirparser usbredir-dev libiscsi-dev sdl2 sdl2-dev libepoxy-dev virglrenderer-dev rdma-core" +
|
||||
" libusb ncurses-libs curl libnfs sdl2 gtk+3.0 fuse libpulse libseccomp jack pipewire liburing";
|
||||
|
||||
public static boolean needreinstallsystem = false;
|
||||
|
||||
public static String temporaryLastedTerminalOutput = "";
|
||||
|
|
|
|||
|
|
@ -10,15 +10,12 @@ import android.view.animation.AnimationUtils;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.Fragment.HomeFragment;
|
||||
import com.vectras.vm.PostActivity;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import com.vectras.vm.MainActivity;
|
||||
|
||||
public class AdapterBlog extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
|
|
@ -27,8 +24,7 @@ public class AdapterBlog extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|||
List<DataBlog> data = Collections.emptyList();
|
||||
DataBlog current;
|
||||
int currentPos = 0;
|
||||
|
||||
// create constructor to innitilize context and data sent from MainActivity
|
||||
|
||||
public AdapterBlog(Context context, List<DataBlog> data) {
|
||||
this.context = context;
|
||||
inflater = LayoutInflater.from(context);
|
||||
|
|
@ -52,9 +48,9 @@ public class AdapterBlog extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|||
final DataBlog current = data.get(position);
|
||||
myHolder.textTitle.setText(current.postTitle);
|
||||
myHolder.textDate.setText("Date: " + current.postDate);
|
||||
Glide.with(MainActivity.activity).load(current.postThumb).into(myHolder.ivThumb);
|
||||
Glide.with(context).load(current.postThumb).into(myHolder.ivThumb);
|
||||
Animation animation;
|
||||
animation = AnimationUtils.loadAnimation(MainActivity.activity, android.R.anim.slide_in_left);
|
||||
animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
|
||||
animation.setDuration(300);
|
||||
|
||||
myHolder.cdPost.startAnimation(animation);
|
||||
|
|
@ -66,7 +62,7 @@ public class AdapterBlog extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|||
PostActivity.content = current.postContent;
|
||||
PostActivity.date = current.postDate;
|
||||
PostActivity.thumb = current.postThumb;
|
||||
MainActivity.activity.startActivity(new Intent(MainActivity.activity, PostActivity.class));
|
||||
context.startActivity(new Intent(context, PostActivity.class));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import android.net.Uri;
|
|||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
|
@ -15,12 +14,12 @@ import androidx.core.app.ActivityCompat;
|
|||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.JSONUtils;
|
||||
import com.vectras.vm.utils.PermissionUtils;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
@ -86,7 +85,7 @@ public class CqcmActivity extends AppCompatActivity {
|
|||
} else {
|
||||
_map = Objects.requireNonNull(getIntent().getStringExtra("content"));
|
||||
}
|
||||
if (JSONUtils.isMapValidFromString(_map)) {
|
||||
if (JSONUtils.isValidFromString(_map)) {
|
||||
mapForCreateNewVM = new Gson().fromJson(_map, new TypeToken<HashMap<String, Object>>(){}.getType());
|
||||
if (mapForCreateNewVM.containsKey("imgName")) {
|
||||
imgName = Objects.requireNonNull(mapForCreateNewVM.get("imgName")).toString();
|
||||
|
|
@ -116,7 +115,7 @@ public class CqcmActivity extends AppCompatActivity {
|
|||
} else {
|
||||
Toast.makeText(getApplicationContext(), "The virtual machine list data is corrupted and new virtual machines cannot be added right now.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
if(!MainActivity.isActivate) {
|
||||
if(!HomeActivity.isActivate) {
|
||||
Log.i("CqcmActivity", "Vectras VM is not opening.");
|
||||
gotoActivity.setClass(getApplicationContext(), SplashActivity.class);
|
||||
startActivity(gotoActivity);
|
||||
|
|
@ -134,7 +133,7 @@ public class CqcmActivity extends AppCompatActivity {
|
|||
private void runCommand(String _command) {
|
||||
AppConfig.pendingCommand = _command;
|
||||
|
||||
if(!MainActivity.isActivate) {
|
||||
if(!HomeActivity.isActivate) {
|
||||
Log.i("CqcmActivity", "Vectras VM is not opening.");
|
||||
gotoActivity.setClass(getApplicationContext(), SplashActivity.class);
|
||||
startActivity(gotoActivity);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import com.vectras.qemu.MainSettingsManager;
|
|||
import com.vectras.vm.Fragment.CreateImageDialogFragment;
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
import com.vectras.vm.databinding.ActivityCustomRomBinding;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.DeviceUtils;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
|
|
@ -525,10 +526,7 @@ public class CustomRomActivity extends AppCompatActivity {
|
|||
createNewVM();
|
||||
} else {
|
||||
DialogUtils.twoDialog(this, getString(R.string.problem_has_been_detected), _contentDialog, getString(R.string.continuetext), getString(R.string.cancel), true, R.drawable.warning_48px, true,
|
||||
() -> {
|
||||
createNewVM();
|
||||
finish();
|
||||
}, null, null);
|
||||
this::createNewVM, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -567,7 +565,7 @@ public class CustomRomActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
modify = false;
|
||||
if (!MainActivity.isActivate) {
|
||||
if (!HomeActivity.isActivate) {
|
||||
startActivity(new Intent(this, SplashActivity.class));
|
||||
} else {
|
||||
Intent openURL = new Intent();
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public class CreateImageDialogFragment extends DialogFragment {
|
|||
}
|
||||
Terminal vterm = new Terminal(getActivity());
|
||||
vterm.executeShellCommand("qemu-img create -f qcow2 \"" + folder + imageName.getText().toString() + ".qcow2\" " +
|
||||
imageSize.getText().toString() + "G", true, getActivity());
|
||||
imageSize.getText().toString() + "G", true, true, getActivity());
|
||||
if (customRom) {
|
||||
if(drive != null)
|
||||
drive.setText(folder + imageName.getText().toString() + ".qcow2");
|
||||
|
|
|
|||
|
|
@ -1,62 +1,27 @@
|
|||
package com.vectras.vm.Fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.AsyncTask;
|
||||
import android.net.NetworkRequest;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.NetworkScanRequest;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.RomsManagerActivity;
|
||||
import com.vectras.vm.MainRoms.AdapterMainRoms;
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.Blog.AdapterBlog;
|
||||
import com.vectras.vm.Blog.DataBlog;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
|
@ -68,7 +33,6 @@ public class HomeFragment extends Fragment {
|
|||
public static RecyclerView mRVMainRoms;
|
||||
public static LinearLayout romsLayout;
|
||||
public static AdapterMainRoms mMainAdapter;
|
||||
public MainActivity activity;
|
||||
public static JSONArray jArray;
|
||||
public static List<DataMainRoms> data;
|
||||
private SwipeRefreshLayout refreshRoms;
|
||||
|
|
@ -79,33 +43,28 @@ public class HomeFragment extends Fragment {
|
|||
|
||||
// TODO show the text view in @layout/home_fragment if list empty
|
||||
|
||||
activity = MainActivity.activity;
|
||||
|
||||
view = inflater.inflate(R.layout.home_fragment, container, false);
|
||||
|
||||
romsLayout = view.findViewById(R.id.romsLayout);
|
||||
|
||||
refreshRoms = view.findViewById(R.id.refreshRoms);
|
||||
|
||||
refreshRoms.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
loadDataVbi();
|
||||
mMainAdapter.notifyItemRangeChanged(0, mMainAdapter.data.size());
|
||||
refreshRoms.setRefreshing(false);
|
||||
}
|
||||
refreshRoms.setOnRefreshListener(() -> {
|
||||
loadDataVbi();
|
||||
mMainAdapter.notifyItemRangeChanged(0, mMainAdapter.data.size());
|
||||
refreshRoms.setRefreshing(false);
|
||||
});
|
||||
loadDataVbi();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public static void loadDataVbi() {
|
||||
private void loadDataVbi() {
|
||||
data = new ArrayList<>();
|
||||
|
||||
try {
|
||||
|
||||
jArray = new JSONArray(FileUtils.readFromFile(MainActivity.activity, new File(AppConfig.maindirpath
|
||||
jArray = new JSONArray(FileUtils.readFromFile(requireActivity(), new File(AppConfig.maindirpath
|
||||
+ "roms-data.json")));
|
||||
|
||||
// Extract data from json and store into ArrayList as class objects
|
||||
|
|
@ -127,7 +86,7 @@ public class HomeFragment extends Fragment {
|
|||
}
|
||||
romsMainData.itemExtra = json_data.getString("imgExtra");
|
||||
try {
|
||||
if (json_data.getString("imgArch").equals(MainSettingsManager.getArch(MainActivity.activity)))
|
||||
if (json_data.getString("imgArch").equals(MainSettingsManager.getArch(requireActivity())))
|
||||
data.add(romsMainData);
|
||||
} catch (JSONException ignored) {
|
||||
data.add(romsMainData);
|
||||
|
|
@ -135,35 +94,12 @@ public class HomeFragment extends Fragment {
|
|||
}
|
||||
|
||||
// Setup and Handover data to recyclerview
|
||||
mRVMainRoms = (RecyclerView) HomeFragment.view.findViewById(R.id.mRVMainRoms);
|
||||
mMainAdapter = new AdapterMainRoms(MainActivity.activity, data);
|
||||
mRVMainRoms = HomeFragment.view.findViewById(R.id.mRVMainRoms);
|
||||
mMainAdapter = new AdapterMainRoms(requireActivity(), data);
|
||||
mRVMainRoms.setAdapter(mMainAdapter);
|
||||
mRVMainRoms.setLayoutManager(new GridLayoutManager(MainActivity.activity, 2));
|
||||
mRVMainRoms.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||
} catch (JSONException e) {
|
||||
Toast.makeText(MainActivity.activity, e.toString(), Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(requireActivity(), e.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CHECK WHETHER INTERNET CONNECTION IS AVAILABLE OR NOT
|
||||
*/
|
||||
public boolean checkConnection(Context context) {
|
||||
final ConnectivityManager connMgr = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
if (connMgr != null) {
|
||||
NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
|
||||
|
||||
if (activeNetworkInfo != null) { // connected to the internet
|
||||
// connected to the mobile provider's data plan
|
||||
if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
|
||||
// connected to wifi
|
||||
return true;
|
||||
} else
|
||||
return activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +1,25 @@
|
|||
package com.vectras.vm.Fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RomsManagerActivity;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.VectrasApp;
|
||||
import com.vectras.vm.adapter.LogsAdapter;
|
||||
import com.vectras.vm.logger.VectrasStatus;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Objects;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,6 @@
|
|||
package com.vectras.vm.MainRoms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
|
|
@ -29,14 +30,15 @@ import java.util.List;
|
|||
|
||||
public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private final Activity activity;
|
||||
private final Context context;
|
||||
private final LayoutInflater inflater;
|
||||
public List<DataMainRoms> data = Collections.emptyList();
|
||||
int currentPos = 0;
|
||||
|
||||
// create constructor to innitilize context and data sent from MainActivity
|
||||
public AdapterMainRoms(Context context, List<DataMainRoms> data) {
|
||||
this.context = context;
|
||||
public AdapterMainRoms(Activity activity, List<DataMainRoms> data) {
|
||||
this.activity = activity;
|
||||
this.context = activity.getApplicationContext();
|
||||
inflater = LayoutInflater.from(context);
|
||||
this.data = data;
|
||||
}
|
||||
|
|
@ -69,15 +71,15 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
}
|
||||
myHolder.optionsBtn.setOnClickListener(view -> {
|
||||
|
||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(MainActivity.activity);
|
||||
View v = MainActivity.activity.getLayoutInflater().inflate(R.layout.rom_options_dialog, null);
|
||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(context);
|
||||
View v = activity.getLayoutInflater().inflate(R.layout.rom_options_dialog, null);
|
||||
bottomSheetDialog.setContentView(v);
|
||||
|
||||
Button modifyRomBtn = v.findViewById(R.id.modifyRomBtn);
|
||||
modifyRomBtn.setOnClickListener(v3 -> {
|
||||
CustomRomActivity.current = data.get(position);
|
||||
VMManager.setArch(current.itemArch, MainActivity.activity);
|
||||
MainActivity.activity.startActivity(new Intent(MainActivity.activity, CustomRomActivity.class).putExtra("POS", position).putExtra("MODIFY", true).putExtra("VMID", current.vmID));
|
||||
VMManager.setArch(current.itemArch, activity);
|
||||
context.startActivity(new Intent(context, CustomRomActivity.class).putExtra("POS", position).putExtra("MODIFY", true).putExtra("VMID", current.vmID));
|
||||
bottomSheetDialog.cancel();
|
||||
});
|
||||
|
||||
|
|
@ -92,14 +94,14 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
|
||||
Button removeRomBtn = v.findViewById(R.id.removeRomBtn);
|
||||
removeRomBtn.setOnClickListener(v1 -> {
|
||||
VMManager.deleteVMDialog(current.itemName, position, MainActivity.activity);
|
||||
VMManager.deleteVMDialog(current.itemName, position, activity);
|
||||
bottomSheetDialog.cancel();
|
||||
});
|
||||
bottomSheetDialog.show();
|
||||
});
|
||||
|
||||
myHolder.cdRoms.setOnClickListener(view -> {
|
||||
VMManager.setArch(current.itemArch, MainActivity.activity);
|
||||
VMManager.setArch(current.itemArch, activity);
|
||||
StartVM.cdrompath = current.imgCdrom;
|
||||
if (current.qmpPort == 0) {
|
||||
Config.setDefault();
|
||||
|
|
@ -107,12 +109,12 @@ public class AdapterMainRoms extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
Config.QMPPort = current.qmpPort;
|
||||
}
|
||||
Config.vmID = current.vmID;
|
||||
String env = StartVM.env(MainActivity.activity, current.itemExtra, current.itemPath, "");
|
||||
String env = StartVM.env(activity, current.itemExtra, current.itemPath, "");
|
||||
MainActivity.startVM(current.itemName, env, current.itemExtra, current.itemPath);
|
||||
});
|
||||
|
||||
myHolder.cdRoms.setOnLongClickListener(v -> {
|
||||
VMManager.deleteVMDialog(current.itemName, position, MainActivity.activity);
|
||||
VMManager.deleteVMDialog(current.itemName, position, activity);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public class MainService extends Service {
|
|||
public static String env = null;
|
||||
private String TAG = "MainService";
|
||||
public static MainService service;
|
||||
public static Activity activity;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
|
@ -49,10 +50,9 @@ public class MainService extends Service {
|
|||
|
||||
if (env != null) {
|
||||
if (service != null) {
|
||||
String filesDir = MainActivity.activity.getFilesDir().getAbsolutePath();
|
||||
Terminal vterm = new Terminal(this);
|
||||
vterm.executeShellCommand2("dwm", false, MainActivity.activity);
|
||||
vterm.executeShellCommand2(env, true, MainActivity.activity);
|
||||
Terminal vterm = new Terminal(activity);
|
||||
vterm.executeShellCommand2("dwm", false, activity);
|
||||
vterm.executeShellCommand2(env, true, activity);
|
||||
}
|
||||
} else
|
||||
Log.e(TAG, "env is null");
|
||||
|
|
@ -69,12 +69,12 @@ public class MainService extends Service {
|
|||
|
||||
//TODO: Not Work
|
||||
//Terminal.killQemuProcess();
|
||||
VMManager.killallqemuprocesses(MainActivity.activity);
|
||||
VMManager.killallqemuprocesses(activity);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
t.setName("StartVM");
|
||||
t.setName("HomeStartVM");
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ public class MainService extends Service {
|
|||
|
||||
//TODO: Not Work
|
||||
//Terminal.killQemuProcess();
|
||||
VMManager.killallqemuprocesses(MainActivity.activity);
|
||||
VMManager.killallqemuprocesses(this);
|
||||
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import androidx.appcompat.widget.Toolbar;
|
|||
|
||||
import com.termux.app.TermuxService;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.CommandUtils;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
|
|
@ -149,7 +150,7 @@ public class Minitools extends AppCompatActivity {
|
|||
reinstallsystem.setOnClickListener(v -> {
|
||||
DialogUtils.twoDialog(Minitools.this, getResources().getString(R.string.reinstall_system), getResources().getString(R.string.reinstall_system_content), getResources().getString(R.string.continuetext), getResources().getString(R.string.cancel), true, R.drawable.system_update_24px, true,
|
||||
() -> {
|
||||
MainActivity.isActivate = false;
|
||||
HomeActivity.isActivate = false;
|
||||
AppConfig.needreinstallsystem = true;
|
||||
VMManager.killallqemuprocesses(Minitools.this);
|
||||
FileUtils.deleteDirectory(getFilesDir().getAbsolutePath() + "/data");
|
||||
|
|
|
|||
|
|
@ -147,8 +147,8 @@ public class ProfileActivity extends AppCompatActivity {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
FirebaseAuth.getInstance().signOut();
|
||||
MainActivity.activity.finish();
|
||||
startActivity(new Intent(activity, SplashActivity.class));
|
||||
finishAffinity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ public class AdapterRomStoreSearch extends RecyclerView.Adapter<RecyclerView.Vie
|
|||
static List<DataRoms> dataRom = Collections.emptyList();
|
||||
private final String TAG = "AdapterRomStoreSearch";
|
||||
|
||||
// create constructor to innitilize context and data sent from MainActivity
|
||||
public AdapterRomStoreSearch(Context context, List<DataRoms> data) {
|
||||
this.context = context;
|
||||
inflater = LayoutInflater.from(context);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ public class AdapterRoms extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|||
static List<DataRoms> dataRom = Collections.emptyList();
|
||||
private final String TAG = "AdapterRoms";
|
||||
|
||||
// create constructor to innitilize context and data sent from MainActivity
|
||||
public AdapterRoms(Context context, List<DataRoms> data) {
|
||||
this.context = context;
|
||||
inflater = LayoutInflater.from(context);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.reflect.TypeToken;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.databinding.ActivitySetupQemuBinding;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.DeviceUtils;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.JSONUtils;
|
||||
|
|
@ -172,7 +173,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
public void onResponse(String tag, String response, HashMap<String, Object> responseHeaders) {
|
||||
linearload.setVisibility(GONE);
|
||||
contentJSON = response;
|
||||
if (JSONUtils.isMapValidFromString(contentJSON)) {
|
||||
if (JSONUtils.isValidFromString(contentJSON)) {
|
||||
mmap.clear();
|
||||
mmap = new Gson().fromJson(contentJSON, new TypeToken<HashMap<String, Object>>() {
|
||||
}.getType());
|
||||
|
|
@ -626,7 +627,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
" echo \"Starting setup...\";" +
|
||||
" apk update;" +
|
||||
" echo \"Installing packages...\";" +
|
||||
" apk add " + AppConfig.neededPkgs.replaceAll(" mesa-vulkan-broadcom mesa-vulkan-freedreno mesa-vulkan-panfrost", "") + ";" +
|
||||
" apk add " + AppConfig.neededPkgs32bit + ";" +
|
||||
//" tar -xzvf " + tarPath + " -C /;" +
|
||||
" echo \"Installing Qemu...\";" +
|
||||
" apk add qemu-system-x86_64 qemu-system-ppc qemu-system-i386 qemu-system-aarch64 qemu-pr-helper qemu-img qemu-audio-sdl pulseaudio mesa-dri-gallium;" +
|
||||
|
|
@ -855,7 +856,7 @@ public class SetupQemuActivity extends AppCompatActivity implements View.OnClick
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!AppConfig.needreinstallsystem) {
|
||||
startActivity(new Intent(SetupQemuActivity.this, MainActivity.class));
|
||||
startActivity(new Intent(SetupQemuActivity.this, HomeActivity.class));
|
||||
} else {
|
||||
AppConfig.needreinstallsystem = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import androidx.core.content.ContextCompat;
|
|||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
|
|
@ -64,15 +65,11 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
|
|||
setContentView(R.layout.activity_splash);
|
||||
UIUtils.setOnApplyWindowInsetsListener(findViewById(R.id.main));
|
||||
|
||||
//TextView textversionname;
|
||||
//textversionname = findViewById(R.id.versionname);
|
||||
//PackageInfo pinfo = MainActivity.activity.getAppInfo(getApplicationContext());
|
||||
//textversionname.setText(pinfo.versionName);
|
||||
setupFolders();
|
||||
SharedPreferences prefs = getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE);
|
||||
|
||||
try {
|
||||
new Handler().postDelayed(activity, 3000);
|
||||
new Handler().postDelayed(activity, 1000);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}/*
|
||||
|
|
@ -350,7 +347,7 @@ public class SplashActivity extends AppCompatActivity implements Runnable {
|
|||
String filesDir = activity.getFilesDir().getAbsolutePath();
|
||||
SharedPreferences prefs = getSharedPreferences(CREDENTIAL_SHARED_PREF, Context.MODE_PRIVATE);
|
||||
if ((new File(filesDir, "/distro/usr/local/bin/qemu-system-x86_64").exists()) || (new File(filesDir, "/distro/usr/bin/qemu-system-x86_64").exists())) {
|
||||
startActivity(new Intent(this, MainActivity.class));
|
||||
startActivity(new Intent(this, HomeActivity.class));
|
||||
} else {
|
||||
startActivity(new Intent(this, SetupQemuActivity.class));
|
||||
//For Android 14+
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ public class StartVM {
|
|||
else if (MainSettingsManager.getArch(activity).equals("PPC"))
|
||||
params.add("qemu-system-ppc");
|
||||
|
||||
params.add("-qmp");
|
||||
params.add("unix:" + Config.getLocalQMPSocketPath() + ",server,nowait");
|
||||
|
||||
String ifType;
|
||||
ifType= MainSettingsManager.getIfType(activity);
|
||||
|
||||
|
|
@ -150,10 +153,10 @@ public class StartVM {
|
|||
}
|
||||
|
||||
String memoryStr = "-m ";
|
||||
if (MainSettingsManager.getArch(activity).equals("PPC") && RamInfo.vectrasMemory() > 2048) {
|
||||
if (MainSettingsManager.getArch(activity).equals("PPC") && RamInfo.vectrasMemory(activity) > 2048) {
|
||||
memoryStr += 2048;
|
||||
} else {
|
||||
memoryStr += RamInfo.vectrasMemory();
|
||||
memoryStr += RamInfo.vectrasMemory(activity);
|
||||
}
|
||||
|
||||
String boot = "-boot ";
|
||||
|
|
@ -168,7 +171,7 @@ public class StartVM {
|
|||
|
||||
//params.add(soundDevice);
|
||||
|
||||
if (MainSettingsManager.useDefaultBios(MainActivity.activity)) {
|
||||
if (MainSettingsManager.useDefaultBios(activity)) {
|
||||
if (MainSettingsManager.getArch(activity).equals("PPC")) {
|
||||
bios = "-L ";
|
||||
bios += "pc-bios";
|
||||
|
|
@ -197,13 +200,13 @@ public class StartVM {
|
|||
params.add(machine);
|
||||
}
|
||||
|
||||
if (MainSettingsManager.useMemoryOvercommit(MainActivity.activity)) {
|
||||
if (MainSettingsManager.useMemoryOvercommit(activity)) {
|
||||
params.add("-overcommit");
|
||||
params.add("mem-lock=off");
|
||||
}
|
||||
|
||||
|
||||
if (MainSettingsManager.useLocalTime(MainActivity.activity)) {
|
||||
if (MainSettingsManager.useLocalTime(activity)) {
|
||||
params.add("-rtc");
|
||||
params.add("base=localtime");
|
||||
}
|
||||
|
|
@ -252,9 +255,9 @@ public class StartVM {
|
|||
|
||||
params.add(vncParams);
|
||||
} else {
|
||||
String qmpParams = "unix:";
|
||||
qmpParams += Config.getLocalVNCSocketPath();
|
||||
params.add(qmpParams);
|
||||
String vncSocketParams = "unix:";
|
||||
vncSocketParams += Config.getLocalVNCSocketPath();
|
||||
params.add(vncSocketParams);
|
||||
}
|
||||
|
||||
//if (!MainSettingsManager.getArch(activity).equals("PPC") || !MainSettingsManager.getArch(activity).equals("ARM64")) {
|
||||
|
|
@ -272,9 +275,6 @@ public class StartVM {
|
|||
|
||||
//params.add("-full-screen");
|
||||
|
||||
params.add("-qmp");
|
||||
params.add("unix:" + Config.getLocalQMPSocketPath() + ",server,nowait");
|
||||
|
||||
return String.join(" ", params);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,11 @@ import android.view.animation.AnimationUtils;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.Fragment.HomeFragment;
|
||||
import com.vectras.vm.PostActivity;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.StoreActivity;
|
||||
import com.vectras.vm.StoreItemActivity;
|
||||
|
||||
|
|
@ -29,8 +25,7 @@ public class AdapterStore extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
List<DataStore> data = Collections.emptyList();
|
||||
DataStore current;
|
||||
int currentPos = 0;
|
||||
|
||||
// create constructor to innitilize context and data sent from MainActivity
|
||||
|
||||
public AdapterStore(Context context, List<DataStore> data) {
|
||||
this.context = context;
|
||||
inflater = LayoutInflater.from(context);
|
||||
|
|
@ -53,10 +48,10 @@ public class AdapterStore extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
MyHolder myHolder = (MyHolder) holder;
|
||||
final DataStore current = data.get(position);
|
||||
myHolder.textName.setText(current.itemName);
|
||||
myHolder.textSize.setText(MainActivity.activity.getString(R.string.size) + current.itemSize);
|
||||
myHolder.textSize.setText(context.getString(R.string.size) + current.itemSize);
|
||||
Glide.with(StoreActivity.activity).load(current.itemIcon).into(myHolder.ivIcon);
|
||||
Animation animation;
|
||||
animation = AnimationUtils.loadAnimation(MainActivity.activity, android.R.anim.slide_in_left);
|
||||
animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
|
||||
animation.setDuration(300);
|
||||
|
||||
myHolder.cdItem.startAnimation(animation);
|
||||
|
|
|
|||
|
|
@ -26,12 +26,15 @@ import androidx.recyclerview.widget.GridLayoutManager;
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.qemu.MainVNCActivity;
|
||||
import com.vectras.qemu.utils.QmpClient;
|
||||
import com.vectras.vm.MainRoms.AdapterMainRoms;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.JSONUtils;
|
||||
|
|
@ -39,6 +42,7 @@ import com.vectras.vm.utils.UIUtils;
|
|||
import com.vectras.vterm.Terminal;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
|
|
@ -142,24 +146,23 @@ public class VMManager {
|
|||
}
|
||||
|
||||
public static void removeInRomsDataJson(Activity _activity, String _vmName, int _position) {
|
||||
MainActivity.mMainAdapter = new AdapterMainRoms(MainActivity.activity, MainActivity.data);
|
||||
MainActivity.data.remove(_position);
|
||||
MainActivity.mRVMainRoms.setAdapter(MainActivity.mMainAdapter);
|
||||
MainActivity.mRVMainRoms.setLayoutManager(new GridLayoutManager(MainActivity.activity, 2));
|
||||
MainActivity.jArray.remove(_position);
|
||||
try {
|
||||
JSONArray jSONArray = new JSONArray(FileUtils.readFromFile(_activity, new File(AppConfig.maindirpath
|
||||
+ "roms-data.json")));
|
||||
jSONArray.remove(_position);
|
||||
|
||||
|
||||
Writer output = null;
|
||||
File jsonFile = new File(AppConfig.maindirpath + "roms-data" + ".json");
|
||||
output = new BufferedWriter(new FileWriter(jsonFile));
|
||||
output.write(MainActivity.jArray.toString());
|
||||
output.write(jSONArray.toString());
|
||||
output.close();
|
||||
} catch (Exception e) {
|
||||
UIUtils.toastLong(_activity, e.toString());
|
||||
}
|
||||
UIUtils.toastLong(_activity, _vmName + _activity.getString(R.string.are_removed_successfully));
|
||||
if (!FileUtils.readAFile(AppConfig.maindirpath + "roms-data.json").contains("{")) {
|
||||
MainActivity.mdatasize2();
|
||||
}
|
||||
|
||||
HomeActivity.refeshVMListNow();
|
||||
}
|
||||
|
||||
public static String idGenerator() {
|
||||
|
|
@ -357,7 +360,7 @@ public class VMManager {
|
|||
if (_startRepeat < _filelist.size()) {
|
||||
if (!isFileExists(_filelist.get((int)(_startRepeat)) + "/vmID.txt")) {
|
||||
if (isFileExists(_filelist.get((int)(_startRepeat)) + "/rom-data.json")) {
|
||||
if (JSONUtils.isMapValidFromString(FileUtils.readAFile(_filelist.get((int)(_startRepeat)) + "/rom-data.json"))) {
|
||||
if (JSONUtils.isValidFromString(FileUtils.readAFile(_filelist.get((int)(_startRepeat)) + "/rom-data.json"))) {
|
||||
if (_resulttemp.toString().contains("}")) {
|
||||
_resulttemp.append(",").append(FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
} else {
|
||||
|
|
@ -428,67 +431,28 @@ public class VMManager {
|
|||
|
||||
public static void startFixRomsDataJson() {
|
||||
int _startRepeat = 0;
|
||||
StringBuilder _resulttemp = new StringBuilder();
|
||||
StringBuilder _result = new StringBuilder();
|
||||
String tempRomData;
|
||||
JsonArray arr = new JsonArray();
|
||||
restoredVMs = 0;
|
||||
ArrayList<String> _filelist = new ArrayList<>();
|
||||
FileUtils.getAListOfAllFilesAndFoldersInADirectory(AppConfig.vmFolder, _filelist);
|
||||
if (!_filelist.isEmpty()) {
|
||||
for (int _repeat = 0; _repeat < (int)(_filelist.size()); _repeat++) {
|
||||
for (int _repeat = 0; _repeat < _filelist.size(); _repeat++) {
|
||||
if (_startRepeat < _filelist.size()) {
|
||||
if (isFileExists(_filelist.get((int)(_startRepeat)) + "/vmID.txt")) {
|
||||
if (isFileExists(_filelist.get((int)(_startRepeat)) + "/rom-data.json")) {
|
||||
if (JSONUtils.isMapValidFromString(FileUtils.readAFile(_filelist.get((int)(_startRepeat)) + "/rom-data.json"))) {
|
||||
if (_resulttemp.toString().contains("}")) {
|
||||
_resulttemp.append(",").append(FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
} else {
|
||||
_resulttemp = new StringBuilder(FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
}
|
||||
if (JSONUtils.isValidFromString(FileUtils.readAFile(AppConfig.maindirpath + "/roms-data.json").replaceAll("]", _resulttemp + "]"))) {
|
||||
if (_result.toString().contains("}")) {
|
||||
_result.append(",").append(FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
} else {
|
||||
_result = new StringBuilder(FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
}
|
||||
restoredVMs++;
|
||||
} else if (JSONUtils.isValidFromString(FileUtils.readAFile(AppConfig.maindirpath + "/roms-data.json").replaceAll("]", "," + _resulttemp + "]"))) {
|
||||
if (_result.toString().contains("}")) {
|
||||
_result.append(",").append(FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
} else {
|
||||
_result = new StringBuilder("," + FileUtils.readAFile(_filelist.get((int) (_startRepeat)) + "/rom-data.json"));
|
||||
}
|
||||
restoredVMs++;
|
||||
} else {
|
||||
Log.i("CqcmActivity", FileUtils.readAFile(AppConfig.maindirpath + "/roms-data.json").replaceAll("]", _resulttemp + "]"));
|
||||
}
|
||||
if (isFileExists(_filelist.get(_startRepeat) + "/vmID.txt")) {
|
||||
if (isFileExists(_filelist.get(_startRepeat) + "/rom-data.json")) {
|
||||
tempRomData = FileUtils.readAFile(_filelist.get(_startRepeat) + "/rom-data.json");
|
||||
if (JSONUtils.isValidFromString(tempRomData)) {
|
||||
arr.add(JsonParser.parseString(tempRomData));
|
||||
restoredVMs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_startRepeat++;
|
||||
if (_startRepeat == _filelist.size()) {
|
||||
if (_result.length() > 0) {
|
||||
if (JSONUtils.isValidFromString("[" + _result + "]")) {
|
||||
if (isFileExists(AppConfig.romsdatajson)) {
|
||||
if (JSONUtils.isValidFromFile(AppConfig.romsdatajson)) {
|
||||
String _JSONcontent = FileUtils.readAFile(AppConfig.romsdatajson);
|
||||
String _JSONcontentnew = _JSONcontent.replaceAll("]", _result + "]");
|
||||
if (JSONUtils.isValidFromString(_JSONcontentnew)) {
|
||||
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", _JSONcontentnew);
|
||||
} else {
|
||||
restoredVMs = 0;
|
||||
}
|
||||
} else {
|
||||
restoredVMs = 0;
|
||||
}
|
||||
} else {
|
||||
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[" + _result + "]");
|
||||
}
|
||||
} else {
|
||||
restoredVMs = 0;
|
||||
}
|
||||
} else {
|
||||
restoredVMs = 0;
|
||||
if (restoredVMs > 0) {
|
||||
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", arr.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -624,7 +588,7 @@ public class VMManager {
|
|||
if (_result.contains("proot\": error=2,")) {
|
||||
DialogUtils.twoDialog(_activity, _activity.getResources().getString(R.string.problem_has_been_detected), _activity.getResources().getString(R.string.error_PROOT_IS_MISSING_0), _activity.getString(R.string.continuetext), _activity.getString(R.string.cancel), true, R.drawable.build_24px, true,
|
||||
() -> {
|
||||
MainActivity.isActivate = false;
|
||||
HomeActivity.isActivate = false;
|
||||
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/data");
|
||||
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/distro");
|
||||
FileUtils.deleteDirectory(_activity.getFilesDir().getAbsolutePath() + "/usr");
|
||||
|
|
@ -650,7 +614,7 @@ public class VMManager {
|
|||
return true;
|
||||
} else if (_result.contains("No such file or directory")) {
|
||||
//Error code: NO_SUCH_FILE_OR_DIRECTORY
|
||||
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_NO_SUCH_FILE_OR_DIRECTORY), _activity.getString(R.string.ok),true, R.drawable.file_copy_24px, true,null, null);
|
||||
DialogUtils.oneDialog(_activity, _activity.getString(R.string.problem_has_been_detected), _activity.getString(R.string.error_NO_SUCH_FILE_OR_DIRECTORY) + "\n\n" + _result, _activity.getString(R.string.ok),true, R.drawable.file_copy_24px, true,null, null);
|
||||
_activity.stopService(new Intent(_activity, MainService.class));
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -687,8 +651,7 @@ public class VMManager {
|
|||
} else {
|
||||
DialogUtils.oneDialog(_context, _context.getString(R.string.done), _context.getString(R.string.roms_data_json_fixed_successfully), _context.getString(R.string.ok),true, R.drawable.check_24px, true,null, null);
|
||||
}
|
||||
MainActivity.mMainAdapter.notifyDataSetChanged();
|
||||
MainActivity.mdatasize2();
|
||||
HomeActivity.refeshVMListNow();
|
||||
movetoRecycleBin();
|
||||
}
|
||||
|
||||
|
|
@ -752,9 +715,9 @@ public class VMManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static boolean isThisVMRunning(String intemExtra, String itemPath) {
|
||||
Terminal vterm = new Terminal(MainActivity.activity);
|
||||
vterm.executeShellCommand2("ps -e", false, MainActivity.activity);
|
||||
public static boolean isThisVMRunning(Activity activity, String intemExtra, String itemPath) {
|
||||
Terminal vterm = new Terminal(activity);
|
||||
vterm.executeShellCommand2("ps -e", false, activity);
|
||||
if (AppConfig.temporaryLastedTerminalOutput.contains(intemExtra) && AppConfig.temporaryLastedTerminalOutput.contains(itemPath)) {
|
||||
Log.d("VMManager.isThisVMRunning", "Yes");
|
||||
return true;
|
||||
|
|
@ -764,9 +727,9 @@ public class VMManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isQemuRunning() {
|
||||
Terminal vterm = new Terminal(MainActivity.activity);
|
||||
vterm.executeShellCommand2("ps -e", false, MainActivity.activity);
|
||||
public static boolean isQemuRunning(Activity activity) {
|
||||
Terminal vterm = new Terminal(activity);
|
||||
vterm.executeShellCommand2("ps -e", false, activity);
|
||||
if (AppConfig.temporaryLastedTerminalOutput.contains("qemu-system")) {
|
||||
Log.d("VMManager.isQemuRunning", "Yes");
|
||||
return true;
|
||||
|
|
@ -795,15 +758,18 @@ public class VMManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static void requestKillAllQemuProcess(Activity activity) {
|
||||
public static void requestKillAllQemuProcess(Activity activity, Runnable runnable) {
|
||||
DialogUtils.twoDialog(activity, activity.getString(R.string.do_you_want_to_kill_all_qemu_processes), activity.getString(R.string.all_running_vms_will_be_forcibly_shut_down), activity.getString(R.string.kill_all), activity.getString(R.string.cancel), true, R.drawable.power_settings_new_24px, true,
|
||||
() -> killallqemuprocesses(activity), null, null);
|
||||
() -> {
|
||||
killallqemuprocesses(activity);
|
||||
if (runnable != null) runnable.run();
|
||||
}, null, null);
|
||||
}
|
||||
|
||||
public static void killcurrentqemuprocess(Context context) {
|
||||
Terminal vterm = new Terminal(context);
|
||||
public static void killcurrentqemuprocess(Activity activity) {
|
||||
Terminal vterm = new Terminal(activity);
|
||||
String env = "killall -9 ";
|
||||
switch (MainSettingsManager.getArch(MainActivity.activity)) {
|
||||
switch (MainSettingsManager.getArch(activity)) {
|
||||
case "ARM64":
|
||||
env += "qemu-system-aarch64";
|
||||
break;
|
||||
|
|
@ -817,15 +783,15 @@ public class VMManager {
|
|||
env += "qemu-system-x86_64";
|
||||
break;
|
||||
}
|
||||
vterm.executeShellCommand2(env, false, MainActivity.activity);
|
||||
vterm.executeShellCommand2(env, false, null);
|
||||
}
|
||||
|
||||
public static void killallqemuprocesses(Context context) {
|
||||
Terminal vterm = new Terminal(context);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-i386", false, MainActivity.activity);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-x86_64", false, MainActivity.activity);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-aarch64", false, MainActivity.activity);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-ppc", false, MainActivity.activity);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-i386", false, null);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-x86_64", false, null);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-aarch64", false, null);
|
||||
vterm.executeShellCommand2("killall -9 qemu-system-ppc", false, null);
|
||||
}
|
||||
|
||||
public static void shutdownCurrentVM() {
|
||||
|
|
@ -1195,4 +1161,18 @@ public class VMManager {
|
|||
|| _qemuCommand.contains("-M pc-q35")
|
||||
|| _qemuCommand.contains("-machine pc-q35");
|
||||
}
|
||||
|
||||
public static boolean checkSharedFolder() { //TODO: not work idk why
|
||||
File folder = new File(AppConfig.sharedFolder);
|
||||
File[] listOfFiles = folder.listFiles();
|
||||
|
||||
if (listOfFiles != null) {
|
||||
for (File file : listOfFiles) {
|
||||
if (file.isFile() && file.length() > 500 * 1024 * 1024) { // 500MB
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public class VectrasApp extends Application {
|
|||
public void onCreate() {
|
||||
super.onCreate();
|
||||
vectrasapp = this;
|
||||
context = new WeakReference<>(getApplicationContext());
|
||||
CrashHandler.getInstance().registerGlobal(this);
|
||||
CrashHandler.getInstance().registerPart(this);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import com.vectras.vm.MainRoms.AdapterMainRoms;
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
|
@ -33,7 +34,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
|||
for (int i=0; i < appWidgetIds.length; i++) {
|
||||
int appWidgetId = appWidgetIds[i];
|
||||
// Create an Intent to launch ExampleActivity
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
Intent intent = new Intent(context, HomeActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
/* context = */ context,
|
||||
/* requestCode = */ 0,
|
||||
|
|
|
|||
844
app/src/main/java/com/vectras/vm/home/HomeActivity.java
Normal file
844
app/src/main/java/com/vectras/vm/home/HomeActivity.java
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
package com.vectras.vm.home;
|
||||
|
||||
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
||||
import static android.content.Intent.ACTION_VIEW;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static com.vectras.vm.VectrasApp.getApp;
|
||||
import static com.vectras.vm.utils.UIUtils.UIAlert;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.StrictMode;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.gson.Gson;
|
||||
import com.termux.app.TermuxActivity;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.AboutActivity;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.CustomRomActivity;
|
||||
import com.vectras.vm.DataExplorerActivity;
|
||||
import com.vectras.vm.Minitools;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RequestNetwork;
|
||||
import com.vectras.vm.RequestNetworkController;
|
||||
import com.vectras.vm.Roms.AdapterRomStoreSearch;
|
||||
import com.vectras.vm.Roms.DataRoms;
|
||||
import com.vectras.vm.RomsManagerActivity;
|
||||
import com.vectras.vm.SetArchActivity;
|
||||
import com.vectras.vm.StoreActivity;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.adapter.LogsAdapter;
|
||||
import com.vectras.vm.databinding.ActivityHomeBinding;
|
||||
import com.vectras.vm.databinding.ActivityHomeContentBinding;
|
||||
import com.vectras.vm.home.core.CallbackInterface;
|
||||
import com.vectras.vm.home.core.DisplaySystem;
|
||||
import com.vectras.vm.home.core.PendingCommand;
|
||||
import com.vectras.vm.home.core.SharedData;
|
||||
import com.vectras.vm.home.monitor.SystemMonitorFragment;
|
||||
import com.vectras.vm.home.romstore.RomStoreFragment;
|
||||
import com.vectras.vm.home.vms.VmsFragment;
|
||||
import com.vectras.vm.home.vms.VmsHomeAdapter;
|
||||
import com.vectras.vm.logger.VectrasStatus;
|
||||
import com.vectras.vm.settings.UpdaterActivity;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.LibraryChecker;
|
||||
import com.vectras.vm.utils.NotificationUtils;
|
||||
import com.vectras.vm.utils.PackageUtils;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HomeActivity extends AppCompatActivity implements RomStoreFragment.RomStoreCallToHomeListener, VmsFragment.VmsCallToHomeListener {
|
||||
|
||||
public static String curRomName;
|
||||
private final String TAG = "HomeActivity";
|
||||
public static boolean isActivate = false;
|
||||
ActivityHomeBinding binding;
|
||||
ActivityHomeContentBinding bindingContent;
|
||||
private AdapterRomStoreSearch adapterRomStoreSearch;
|
||||
private final List<DataRoms> dataRomStoreSearch = new ArrayList<>();
|
||||
|
||||
public static CallbackInterface.HomeCallToVmsListener homeCallToVmsListener;
|
||||
|
||||
public static void refeshVMListNow() {
|
||||
homeCallToVmsListener.refeshVMList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDataStatus(boolean isReady) {
|
||||
bindingContent.searchbar.setEnabled(isReady);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openRomStore() {
|
||||
bindingContent.bottomNavigation.setSelectedItemId(R.id.item_romstore);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
||||
StrictMode.setThreadPolicy(policy);
|
||||
|
||||
VmsFragment.vmsCallToHomeListener = this;
|
||||
RomStoreFragment.romStoreCallToHomeListener = this;
|
||||
|
||||
EdgeToEdge.enable(this);
|
||||
binding = ActivityHomeBinding.inflate(getLayoutInflater());
|
||||
bindingContent = binding.maincontent;
|
||||
setContentView(binding.getRoot());
|
||||
isActivate = true;
|
||||
|
||||
UIUtils.setOnApplyWindowInsetsListener(bindingContent.main);
|
||||
UIUtils.setOnApplyWindowInsetsListenerLeftOnly(binding.navView);
|
||||
UIUtils.setOnApplyWindowInsetsListenerBottomOnly(binding.rvRomstoresearch);
|
||||
UIUtils.setOnApplyWindowInsetsListenerBottomOnly(binding.lnSearchempty);
|
||||
|
||||
initialize(bundle);
|
||||
}
|
||||
|
||||
private void initialize(Bundle savedInstanceState) {
|
||||
bindingContent.efabCreate.setOnClickListener(view -> startActivity(new Intent(this, SetArchActivity.class)));
|
||||
|
||||
setSupportActionBar(bindingContent.toolbar);
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
}
|
||||
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, binding.drawerLayout, bindingContent.toolbar,
|
||||
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
||||
binding.drawerLayout.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(bindingContent.containerView.getId(), new VmsFragment())
|
||||
.commit();
|
||||
}
|
||||
|
||||
binding.searchview.setupWithSearchBar(bindingContent.searchbar);
|
||||
|
||||
bindingContent.searchbar.inflateMenu(R.menu.searchbar_menu);
|
||||
bindingContent.searchbar.setOnMenuItemClickListener(
|
||||
menuItem -> {
|
||||
if (menuItem.getItemId() == R.id.importrom) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), CustomRomActivity.class);
|
||||
intent.putExtra("importcvbinow", "");
|
||||
startActivity(intent);
|
||||
} else if (menuItem.getItemId() == R.id.backtothedisplay) {
|
||||
DisplaySystem.launch(this);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
bindingContent.searchbar.setEnabled(false);
|
||||
|
||||
bindingContent.bottomNavigation.setOnItemSelectedListener(item -> {
|
||||
Fragment selectedFragment;
|
||||
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.item_home) {
|
||||
selectedFragment = new VmsFragment();
|
||||
bindingContent.efabCreate.setVisibility(View.VISIBLE);
|
||||
bindingContent.searchbar.setHint(getText(R.string.home));
|
||||
bindingContent.searchbar.setEnabled(false);
|
||||
} else if (id == R.id.item_romstore) {
|
||||
selectedFragment = new RomStoreFragment();
|
||||
bindingContent.efabCreate.setVisibility(View.GONE);
|
||||
bindingContent.searchbar.setEnabled(true);
|
||||
bindingContent.searchbar.setHint(getText(R.string.search));
|
||||
} else if (id == R.id.item_monitor) {
|
||||
selectedFragment = new SystemMonitorFragment();
|
||||
bindingContent.efabCreate.setVisibility(View.GONE);
|
||||
bindingContent.searchbar.setHint(getText(R.string.system_monitor));
|
||||
bindingContent.searchbar.setEnabled(false);
|
||||
} else {
|
||||
selectedFragment = new VmsFragment();
|
||||
bindingContent.efabCreate.setVisibility(View.VISIBLE);
|
||||
bindingContent.searchbar.setHint(getText(R.string.home));
|
||||
bindingContent.searchbar.setEnabled(false);
|
||||
}
|
||||
|
||||
if (selectedFragment != null) {
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(bindingContent.containerView.getId(), selectedFragment)
|
||||
.commit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
binding.drawerLayout.closeDrawer(GravityCompat.START);
|
||||
} else {
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
adapterRomStoreSearch = new AdapterRomStoreSearch(this, dataRomStoreSearch);
|
||||
binding.rvRomstoresearch.setAdapter(adapterRomStoreSearch);
|
||||
binding.rvRomstoresearch.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
|
||||
|
||||
binding.searchview.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
search(s.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence newText, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
new LibraryChecker(this).checkMissingLibraries(this);
|
||||
|
||||
setupDrawer();
|
||||
DisplaySystem.startTermuxX11();
|
||||
DialogUtils.joinTelegram(this);
|
||||
NotificationUtils.clearAll(this);
|
||||
|
||||
if (MainSettingsManager.getPromptUpdateVersion(this))
|
||||
updateApp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
homeCallToVmsListener.configurationChanged(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
isActivate = false;
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.home_toolbar_menu, menu);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
// Menu items
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.shutdown) {
|
||||
VMManager.requestKillAllQemuProcess(this, null);
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume");
|
||||
Config.ui = MainSettingsManager.getVmUi(this);
|
||||
Config.defaultVNCPort = Integer.parseInt(MainSettingsManager.getVncExternalDisplay(this));
|
||||
|
||||
if (!MainSettingsManager.getVncExternal(this))
|
||||
NotificationUtils.clearAll(this);
|
||||
Config.ui = MainSettingsManager.getVmUi(this);
|
||||
|
||||
DisplaySystem.reLaunchVNC(this);
|
||||
PendingCommand.runNow(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent ReturnedIntent) {
|
||||
super.onActivityResult(requestCode, resultCode, ReturnedIntent);
|
||||
if (requestCode == 1004 && resultCode == RESULT_OK) {
|
||||
Uri content_describer = ReturnedIntent.getData();
|
||||
File selectedFilePath = new File(getPath(content_describer));
|
||||
ProgressBar loading = findViewById(R.id.loading);
|
||||
if (selectedFilePath.toString().endsWith(".iso")) {
|
||||
loading.setVisibility(View.VISIBLE);
|
||||
new Thread(() -> {
|
||||
FileInputStream File;
|
||||
try {
|
||||
assert content_describer != null;
|
||||
File = (FileInputStream) getContentResolver().openInputStream(content_describer);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
try (OutputStream out = new FileOutputStream(AppConfig.maindirpath + "/drive.iso")) {
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while (true) {
|
||||
assert File != null;
|
||||
if (!((len = File.read(buf)) > 0)) break;
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Runnable runnable = () -> loading.setVisibility(View.GONE);
|
||||
runOnUiThread(runnable);
|
||||
assert File != null;
|
||||
File.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Runnable runnable = () -> {
|
||||
loading.setVisibility(View.GONE);
|
||||
UIAlert(this, e.toString(), "error");
|
||||
};
|
||||
runOnUiThread(runnable);
|
||||
}
|
||||
}).start();
|
||||
} else
|
||||
UIAlert(this, "please select iso file", "INVALID FILE");
|
||||
} else if (requestCode == 1005 && resultCode == RESULT_OK) {
|
||||
Uri content_describer = ReturnedIntent.getData();
|
||||
ProgressBar loading = findViewById(R.id.loading);
|
||||
loading.setVisibility(View.VISIBLE);
|
||||
new Thread(() -> {
|
||||
FileInputStream File;
|
||||
try {
|
||||
assert content_describer != null;
|
||||
File = (FileInputStream) getContentResolver().openInputStream(content_describer);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
try (OutputStream out = new FileOutputStream(AppConfig.maindirpath + "/hdd1.qcow2")) {
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while (true) {
|
||||
assert File != null;
|
||||
if (!((len = File.read(buf)) > 0)) break;
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Runnable runnable = () -> loading.setVisibility(View.GONE);
|
||||
runOnUiThread(runnable);
|
||||
assert File != null;
|
||||
File.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Runnable runnable = () -> {
|
||||
loading.setVisibility(View.GONE);
|
||||
UIAlert(this, e.toString(), "error");
|
||||
};
|
||||
runOnUiThread(runnable);
|
||||
}
|
||||
}).start();
|
||||
} else if (requestCode == 1006 && resultCode == RESULT_OK) {
|
||||
Uri content_describer = ReturnedIntent.getData();
|
||||
ProgressBar loading = findViewById(R.id.loading);
|
||||
loading.setVisibility(View.VISIBLE);
|
||||
new Thread(() -> {
|
||||
FileInputStream File;
|
||||
try {
|
||||
assert content_describer != null;
|
||||
File = (FileInputStream) getContentResolver().openInputStream(content_describer);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
try (OutputStream out = new FileOutputStream(AppConfig.maindirpath + "/hdd2.qcow2")) {
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while (true) {
|
||||
assert File != null;
|
||||
if (!((len = File.read(buf)) > 0)) break;
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Runnable runnable = () -> loading.setVisibility(View.GONE);
|
||||
runOnUiThread(runnable);
|
||||
assert File != null;
|
||||
File.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Runnable runnable = () -> {
|
||||
loading.setVisibility(View.GONE);
|
||||
UIAlert(this, e.toString(), "error");
|
||||
};
|
||||
runOnUiThread(runnable);
|
||||
}
|
||||
}).start();
|
||||
} else if (requestCode == 122 && resultCode == RESULT_OK) {
|
||||
Uri content_describer = ReturnedIntent.getData();
|
||||
File selectedFilePath = new File(getPath(content_describer));
|
||||
ProgressBar loading = findViewById(R.id.loading);
|
||||
loading.setVisibility(View.VISIBLE);
|
||||
new Thread(() -> {
|
||||
FileInputStream File;
|
||||
try {
|
||||
assert content_describer != null;
|
||||
File = (FileInputStream) getContentResolver().openInputStream(content_describer);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
File romDir = new File(AppConfig.maindirpath + curRomName + "/");
|
||||
if (!romDir.exists()) {
|
||||
if(!romDir.mkdirs()) return;
|
||||
}
|
||||
try (OutputStream out = new FileOutputStream(AppConfig.maindirpath + curRomName + "/" + "drv1-" + selectedFilePath.getName())) {
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while (true) {
|
||||
assert File != null;
|
||||
if (!((len = File.read(buf)) > 0)) break;
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Runnable runnable = () -> loading.setVisibility(View.GONE);
|
||||
runOnUiThread(runnable);
|
||||
assert File != null;
|
||||
File.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Runnable runnable = () -> {
|
||||
loading.setVisibility(View.GONE);
|
||||
UIAlert(this, e.toString(), "error");
|
||||
};
|
||||
runOnUiThread(runnable);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
public String getPath(Uri uri) {
|
||||
return FileUtils.getPath(this, uri);
|
||||
}
|
||||
|
||||
private void setupDrawer() {
|
||||
binding.drawerLayout.setScrimColor(Color.parseColor("#40000000")); //25%
|
||||
|
||||
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
|
||||
// This method will trigger on item Click of navigation menu
|
||||
binding.navView.setNavigationItemSelectedListener(menuItem -> {
|
||||
//Closing drawer on item click
|
||||
binding.drawerLayout.closeDrawers();
|
||||
|
||||
//Check to see which item was being clicked and perform appropriate action
|
||||
int id = menuItem.getItemId();
|
||||
if (id == R.id.navigation_item_info) {
|
||||
startActivity(new Intent(this, AboutActivity.class));
|
||||
}
|
||||
if (id == R.id.navigation_item_help) {
|
||||
String tw = AppConfig.vectrasHelp;
|
||||
Intent w = new Intent(ACTION_VIEW);
|
||||
w.setData(Uri.parse(tw));
|
||||
startActivity(w);
|
||||
} else if (id == R.id.navigation_item_website) {
|
||||
String tw = AppConfig.vectrasWebsite;
|
||||
Intent w = new Intent(ACTION_VIEW);
|
||||
w.setData(Uri.parse(tw));
|
||||
startActivity(w);
|
||||
} else if (id == R.id.navigation_item_import_iso) {
|
||||
if (new File(AppConfig.maindirpath + "/drive.iso").exists()) {
|
||||
AlertDialog ad;
|
||||
ad = new AlertDialog.Builder(this, R.style.MainDialogTheme).create();
|
||||
ad.setTitle("REPLACE ISO");
|
||||
ad.setMessage("there is iso imported you want to replace it?");
|
||||
ad.setButton(Dialog.BUTTON_POSITIVE, "REPLACE", (dialog, which) -> {
|
||||
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
// Optionally, specify a URI for the file that should appear in the
|
||||
// system file picker when it loads.
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
startActivityForResult(intent, 1004);
|
||||
});
|
||||
ad.setButton(Dialog.BUTTON_NEGATIVE, "REMOVE", (dialog, which) -> {
|
||||
File isoFile = new File(AppConfig.maindirpath + "/drive.iso");
|
||||
try {
|
||||
if(!isoFile.delete()) Log.e(TAG, "Delete drive.iso failed!");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Delete drive.iso: ", e);
|
||||
}
|
||||
});
|
||||
ad.show();
|
||||
} else {
|
||||
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
// Optionally, specify a URI for the file that should appear in the
|
||||
// system file picker when it loads.
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
startActivityForResult(intent, 1004);
|
||||
}
|
||||
} else if (id == R.id.navigation_item_hdd1) {
|
||||
if (new File(AppConfig.maindirpath + "/hdd1.qcow2").exists()) {
|
||||
AlertDialog ad;
|
||||
ad = new AlertDialog.Builder(this, R.style.MainDialogTheme).create();
|
||||
ad.setTitle("REPLACE HDD1");
|
||||
ad.setMessage("there is hdd1 imported you want to replace it?");
|
||||
ad.setButton(Dialog.BUTTON_POSITIVE, "REPLACE", (dialog, which) -> {
|
||||
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
// Optionally, specify a URI for the file that should appear in the
|
||||
// system file picker when it loads.
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
startActivityForResult(intent, 1006);
|
||||
});
|
||||
ad.setButton(Dialog.BUTTON_NEGATIVE, "REMOVE", (dialog, which) -> {
|
||||
File isoFile = new File(AppConfig.maindirpath + "/hdd1.qcow2");
|
||||
try {
|
||||
if(!isoFile.delete()) Log.e(TAG, "Delete hdd1.qcow2 failed!");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Delete hdd1.qcow2: ", e);
|
||||
}
|
||||
});
|
||||
ad.setButton(Dialog.BUTTON_NEUTRAL, "SHARE", (dialog, which) -> {
|
||||
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
||||
File fileWithinMyDir = new File(AppConfig.maindirpath + "/hdd1.qcow2");
|
||||
|
||||
if (fileWithinMyDir.exists()) {
|
||||
intentShareFile.setType("*/*");
|
||||
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + AppConfig.maindirpath + "/hdd1.qcow2"));
|
||||
|
||||
intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
|
||||
"Sharing File...");
|
||||
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
|
||||
|
||||
startActivity(Intent.createChooser(intentShareFile, "Share File"));
|
||||
}
|
||||
});
|
||||
ad.show();
|
||||
} else {
|
||||
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
// Optionally, specify a URI for the file that should appear in the
|
||||
// system file picker when it loads.
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
startActivityForResult(intent, 1005);
|
||||
}
|
||||
} else if (id == R.id.navigation_item_hdd2) {
|
||||
if (new File(AppConfig.maindirpath + "/hdd2.qcow2").exists()) {
|
||||
AlertDialog ad;
|
||||
ad = new AlertDialog.Builder(this, R.style.MainDialogTheme).create();
|
||||
ad.setTitle("REPLACE HDD2");
|
||||
ad.setMessage("there is hdd2 imported you want to replace it?");
|
||||
ad.setButton(Dialog.BUTTON_POSITIVE, "REPLACE", (dialog, which) -> {
|
||||
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
// Optionally, specify a URI for the file that should appear in the
|
||||
// system file picker when it loads.
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
startActivityForResult(intent, 1006);
|
||||
});
|
||||
ad.setButton(Dialog.BUTTON_NEGATIVE, "REMOVE", (dialog, which) -> {
|
||||
File isoFile = new File(AppConfig.maindirpath + "/hdd2.qcow2");
|
||||
try {
|
||||
if(!isoFile.delete()) Log.e(TAG, "Delete hdd2.qcow2 failed!");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Delete hdd2.qcow2: ", e);
|
||||
}
|
||||
});
|
||||
ad.setButton(Dialog.BUTTON_NEUTRAL, "SHARE", (dialog, which) -> {
|
||||
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
||||
File fileWithinMyDir = new File(AppConfig.maindirpath + "/hdd2.qcow2");
|
||||
|
||||
if (fileWithinMyDir.exists()) {
|
||||
intentShareFile.setType("*/*");
|
||||
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + AppConfig.maindirpath + "/hdd2.qcow2"));
|
||||
|
||||
intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
|
||||
"Sharing File...");
|
||||
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
|
||||
|
||||
startActivity(Intent.createChooser(intentShareFile, "Share File"));
|
||||
}
|
||||
});
|
||||
ad.show();
|
||||
} else {
|
||||
Intent intent = new Intent(ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
// Optionally, specify a URI for the file that should appear in the
|
||||
// system file picker when it loads.
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Environment.DIRECTORY_DOWNLOADS);
|
||||
}
|
||||
|
||||
startActivityForResult(intent, 1006);
|
||||
}
|
||||
} else if (id == R.id.navigation_item_desktop) {
|
||||
DisplaySystem.launchX11(this, true);
|
||||
} else if (id == R.id.navigation_item_terminal) {
|
||||
/*com.vectras.vterm.TerminalBottomSheetDialog VTERM = new com.vectras.vterm.TerminalBottomSheetDialog(activity);
|
||||
VTERM.showVterm();*/
|
||||
startActivity(new Intent(this, TermuxActivity.class));
|
||||
} else if (id == R.id.navigation_item_view_logs) {
|
||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);
|
||||
View view = getLayoutInflater().inflate(R.layout.bottomsheetdialog_logger, null);
|
||||
bottomSheetDialog.setContentView(view);
|
||||
bottomSheetDialog.show();
|
||||
|
||||
// final String CREDENTIAL_SHARED_PREF = "settings_prefs";
|
||||
Timer _timer = new Timer();
|
||||
TimerTask t;
|
||||
|
||||
LinearLayoutManager layoutManager = new LinearLayoutManager(getApp());
|
||||
LogsAdapter mLogAdapter = new LogsAdapter(layoutManager, getApp());
|
||||
RecyclerView logList = view.findViewById(R.id.recyclerLog);
|
||||
logList.setAdapter(mLogAdapter);
|
||||
logList.setLayoutManager(layoutManager);
|
||||
mLogAdapter.scrollToLastPosition();
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("logcat -e");
|
||||
BufferedReader bufferedReader = new BufferedReader(
|
||||
new InputStreamReader(process.getInputStream()));
|
||||
Process process2 = Runtime.getRuntime().exec("logcat -w");
|
||||
BufferedReader bufferedReader2 = new BufferedReader(
|
||||
new InputStreamReader(process2.getInputStream()));
|
||||
|
||||
t = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
runOnUiThread(() -> {
|
||||
try {
|
||||
if (bufferedReader.readLine() != null || bufferedReader2.readLine() != null) {
|
||||
String logLine = bufferedReader.readLine();
|
||||
String logLine2 = bufferedReader2.readLine();
|
||||
VectrasStatus.logError("<font color='red'>[E] " + logLine + "</font>");
|
||||
VectrasStatus.logError("<font color='#FFC107'>[W] " + logLine2 + "</font>");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
_timer.scheduleAtFixedRate(t, 0, 100);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Log: ", e);
|
||||
}
|
||||
} else if (id == R.id.navigation_item_settings) {
|
||||
startActivity(new Intent(this, MainSettingsManager.class));
|
||||
} else if (id == R.id.navigation_item_store) {
|
||||
startActivity(new Intent(this, StoreActivity.class));
|
||||
} else if (id == R.id.navigation_data_explorer) {
|
||||
startActivity(new Intent(this, DataExplorerActivity.class));
|
||||
} else if (id == R.id.navigation_item_donate) {
|
||||
String tw = "https://www.patreon.com/VectrasTeam";
|
||||
Intent w = new Intent(ACTION_VIEW);
|
||||
w.setData(Uri.parse(tw));
|
||||
startActivity(w);
|
||||
} else if (id == R.id.navigation_item_get_rom) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(getApplicationContext(), RomsManagerActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.mini_tools) {
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(this, Minitools.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private void updateApp() {
|
||||
int versionCode = PackageUtils.getThisVersionCode(getApplicationContext());
|
||||
String versionName = PackageUtils.getThisVersionName(getApplicationContext());
|
||||
|
||||
RequestNetwork requestNetwork = new RequestNetwork(this);
|
||||
RequestNetwork.RequestListener requestNetworkListener = new RequestNetwork.RequestListener() {
|
||||
@Override
|
||||
public void onResponse(String tag, String response, HashMap<String, Object> responseHeaders) {
|
||||
if (!response.isEmpty()) {
|
||||
try {
|
||||
final JSONObject obj = new JSONObject(response);
|
||||
String versionNameonUpdate;
|
||||
int versionCodeonUpdate;
|
||||
// String message;
|
||||
// String size;
|
||||
|
||||
if (MainSettingsManager.getcheckforupdatesfromthebetachannel(HomeActivity.this)) {
|
||||
versionNameonUpdate = obj.getString("versionNameBeta");
|
||||
versionCodeonUpdate = obj.getInt("versionCodeBeta");
|
||||
// message = obj.getString("MessageBeta");
|
||||
// size = obj.getString("sizeBeta");
|
||||
} else {
|
||||
versionNameonUpdate = obj.getString("versionName");
|
||||
versionCodeonUpdate = obj.getInt("versionCode");
|
||||
// message = obj.getString("Message");
|
||||
// size = obj.getString("size");
|
||||
}
|
||||
|
||||
if ((versionCode < versionCodeonUpdate ||
|
||||
!versionNameonUpdate.equals(versionName)) &&
|
||||
!MainSettingsManager.getSkipVersion(HomeActivity.this).equals(versionNameonUpdate)) {
|
||||
|
||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(HomeActivity.this);
|
||||
View v = getLayoutInflater().inflate(R.layout.update_bottom_dialog_layout, null);
|
||||
bottomSheetDialog.setContentView(v);
|
||||
|
||||
// TextView tvContent = v.findViewById(R.id.tv_content);
|
||||
MaterialButton skipButton = v.findViewById(R.id.bn_skip);
|
||||
MaterialButton laterButton = v.findViewById(R.id.bn_later);
|
||||
MaterialButton updateButton = v.findViewById(R.id.bn_update);
|
||||
|
||||
// tvContent.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
// tvContent.setText(Html.fromHtml(message + "<br><br>Update size:<br>" + size));
|
||||
|
||||
skipButton.setOnClickListener(view -> {
|
||||
MainSettingsManager.setSkipVersion(HomeActivity.this, versionNameonUpdate);
|
||||
bottomSheetDialog.dismiss();
|
||||
});
|
||||
|
||||
laterButton.setOnClickListener(view -> bottomSheetDialog.dismiss());
|
||||
|
||||
updateButton.setOnClickListener(view -> {
|
||||
startActivity(new Intent(HomeActivity.this, UpdaterActivity.class));
|
||||
bottomSheetDialog.dismiss();
|
||||
});
|
||||
|
||||
bottomSheetDialog.show();
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "updateApp: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onErrorResponse(String tag, String message) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
requestNetwork.startRequestNetwork(RequestNetworkController.GET,AppConfig.updateJson,"maincheckupdate",requestNetworkListener);
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private void search(String keyword) {
|
||||
try {
|
||||
// Extract data from json and store into ArrayList as class objects
|
||||
Gson gson = new Gson();
|
||||
List<DataRoms> filteredData = new ArrayList<>();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
filteredData = SharedData.dataRomStore.stream()
|
||||
.filter(rom -> {
|
||||
String romName = (rom.romName != null) ? rom.romName : "";
|
||||
String romKernel = (rom.romKernel != null) ? rom.romKernel : "";
|
||||
|
||||
return romName.toLowerCase().contains(keyword.toLowerCase())
|
||||
|| romKernel.toLowerCase().contains(keyword.toLowerCase());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
for (DataRoms rom : SharedData.dataRomStore) {
|
||||
if (rom.romName.toLowerCase().contains(keyword.toLowerCase()) ||
|
||||
rom.romKernel.toLowerCase().contains(keyword.toLowerCase())) {
|
||||
filteredData.add(rom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dataRomStoreSearch.clear();
|
||||
dataRomStoreSearch.addAll(filteredData);
|
||||
} catch (Exception e) {
|
||||
Log.e("RomManagerActivity", "Json parsing error: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (dataRomStoreSearch.isEmpty())
|
||||
binding.rvRomstoresearch.setVisibility(View.GONE);
|
||||
else
|
||||
binding.rvRomstoresearch.setVisibility(View.VISIBLE);
|
||||
|
||||
adapterRomStoreSearch.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.vectras.vm.home.core;
|
||||
|
||||
public class CallbackInterface {
|
||||
//Fix Cyclic.
|
||||
public interface HomeCallToVmsListener {
|
||||
void refeshVMList();
|
||||
void configurationChanged(boolean isLandscape);
|
||||
}
|
||||
}
|
||||
105
app/src/main/java/com/vectras/vm/home/core/DisplaySystem.java
Normal file
105
app/src/main/java/com/vectras/vm/home/core/DisplaySystem.java
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
package com.vectras.vm.home.core;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static com.vectras.vm.utils.LibraryChecker.isPackageInstalled2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
import com.termux.app.TermuxService;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.qemu.MainVNCActivity;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.core.ShellExecutor;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.x11.X11Activity;
|
||||
import com.vectras.vterm.Terminal;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class DisplaySystem {
|
||||
public static void launch(Activity activity) {
|
||||
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
|
||||
activity.startActivity(new Intent(activity, MainVNCActivity.class));
|
||||
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
|
||||
DisplaySystem.launchX11(activity, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reLaunchVNC(Activity activity) {
|
||||
if (MainSettingsManager.getVmUi(activity).equals("VNC") &&
|
||||
FileUtils.isFileExists(Config.getLocalQMPSocketPath()) &&
|
||||
!activity.isFinishing() &&
|
||||
MainVNCActivity.started)
|
||||
activity.startActivity(new Intent(activity, MainVNCActivity.class));
|
||||
}
|
||||
|
||||
public static void launchX11(Activity activity, boolean isKillXFCE) {
|
||||
if (SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
DialogUtils.oneDialog(
|
||||
activity,
|
||||
activity.getString(R.string.x11_feature_not_supported),
|
||||
activity.getString(R.string.the_x11_feature_is_currently_not_supported_on_android_14_and_above_please_use_a_device_with_android_13_or_below_for_x11_functionality),
|
||||
activity.getString(R.string.ok),
|
||||
true, R.drawable.error_96px,
|
||||
true,
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
// XFCE4 meta-package
|
||||
String xfce4Package = "xfce4";
|
||||
|
||||
// Check if XFCE4 is installed
|
||||
isPackageInstalled2(activity, xfce4Package, (output, errors) -> {
|
||||
boolean isInstalled = false;
|
||||
|
||||
// Check if the package exists in the installed packages output
|
||||
if (output != null) {
|
||||
Set<String> installedPackages = new HashSet<>();
|
||||
for (String installedPackage : output.split("\n")) {
|
||||
installedPackages.add(installedPackage.trim());
|
||||
}
|
||||
|
||||
isInstalled = installedPackages.contains(xfce4Package.trim());
|
||||
}
|
||||
|
||||
// If not installed, show a dialog to install it
|
||||
if (!isInstalled) {
|
||||
DialogUtils.twoDialog(
|
||||
activity,
|
||||
"Install XFCE4",
|
||||
"XFCE4 is not installed. Would you like to install it?",
|
||||
activity.getString(R.string.install),
|
||||
activity.getString(R.string.cancel),
|
||||
true,
|
||||
R.drawable.desktop_24px,
|
||||
true,
|
||||
() -> {
|
||||
String installCommand = "apk add " + xfce4Package;
|
||||
new Terminal(activity).executeShellCommand(installCommand, true, true, activity);
|
||||
},
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
if (isKillXFCE)
|
||||
new Terminal(activity).executeShellCommand2("killall xfce4-session", false, activity);
|
||||
activity.startActivity(new Intent(activity, X11Activity.class));
|
||||
new Terminal(activity).executeShellCommand2("xfce4-session", false, activity);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void startTermuxX11() {
|
||||
if (Build.VERSION.SDK_INT < 34) {
|
||||
ShellExecutor shellExec = new ShellExecutor();
|
||||
shellExec.exec(TermuxService.PREFIX_PATH + "/bin/termux-x11 :0");
|
||||
}
|
||||
}
|
||||
}
|
||||
184
app/src/main/java/com/vectras/vm/home/core/HomeStartVM.java
Normal file
184
app/src/main/java/com/vectras/vm/home/core/HomeStartVM.java
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package com.vectras.vm.home.core;
|
||||
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.qemu.MainVNCActivity;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.MainService;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.logger.VectrasStatus;
|
||||
import com.vectras.vm.settings.VNCActivity;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.NetworkUtils;
|
||||
import com.vectras.vm.utils.ServiceUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class HomeStartVM {
|
||||
public static AlertDialog progressDialog;
|
||||
|
||||
public static boolean skipIDEwithARM64DialogInStartVM = false;
|
||||
|
||||
public static void startNow(
|
||||
Activity activity,
|
||||
String vmName,
|
||||
String env,
|
||||
String itemExtra,
|
||||
String itemPath,
|
||||
AppBarLayout appbar,
|
||||
LinearLayout extVncLayout
|
||||
) {
|
||||
File romDir = new File(Config.getCacheDir() + "/" + Config.vmID);
|
||||
if (!romDir.exists()) {
|
||||
if (!romDir.mkdirs()) {
|
||||
DialogUtils.oneDialog(activity, activity.getString(R.string.problem_has_been_detected), activity.getString(R.string.vm_cache_dir_failed_to_create_content), activity.getString(R.string.ok), true, R.drawable.warning_48px, true, null, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!VMManager.isthiscommandsafe(env, activity.getApplicationContext())) {
|
||||
DialogUtils.oneDialog(activity, activity.getString(R.string.problem_has_been_detected), activity.getString(R.string.harmful_command_was_detected) + " " + activity.getResources().getString(R.string.reason) + ": " + VMManager.latestUnsafeCommandReason, activity.getString(R.string.ok), true, R.drawable.verified_user_24px, true, null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager.lastQemuCommand = env;
|
||||
|
||||
if (VMManager.isThisVMRunning(activity, itemExtra, itemPath)) {
|
||||
Toast.makeText(activity, "This VM is already running.", Toast.LENGTH_LONG).show();
|
||||
if (MainSettingsManager.getVmUi(activity).equals("VNC"))
|
||||
activity.startActivity(new Intent(activity, MainVNCActivity.class));
|
||||
else if (MainSettingsManager.getVmUi(activity).equals("X11"))
|
||||
DisplaySystem.launchX11(activity, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AppConfig.getSetupFiles().contains("arm") && !AppConfig.getSetupFiles().contains("arm64")) {
|
||||
if (env.contains("tcg,thread=multi")) {
|
||||
DialogUtils.twoDialog(activity, activity.getResources().getString(R.string.problem_has_been_detected), activity.getResources().getString(R.string.can_not_use_mttcg), activity.getString(R.string.ok), activity.getString(R.string.cancel), true, R.drawable.warning_48px, true,
|
||||
() -> startNow(activity, vmName, env.replace("tcg,thread=multi", "tcg,thread=single"), itemExtra, itemPath, appbar, extVncLayout), null, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MainSettingsManager.getArch(activity).equals("ARM64") && MainSettingsManager.getIfType(activity).equals("ide") && skipIDEwithARM64DialogInStartVM) {
|
||||
DialogUtils.twoDialog(activity, activity.getString(R.string.problem_has_been_detected), activity.getString(R.string.you_cannot_use_IDE_hard_drive_type_with_ARM64), activity.getString(R.string.continuetext), activity.getString(R.string.cancel), true, R.drawable.warning_48px, true,
|
||||
() -> {
|
||||
skipIDEwithARM64DialogInStartVM = true;
|
||||
startNow(activity, vmName, env, itemExtra, itemPath, appbar, extVncLayout);
|
||||
}, null, null);
|
||||
return;
|
||||
} else if (skipIDEwithARM64DialogInStartVM) {
|
||||
skipIDEwithARM64DialogInStartVM = false;
|
||||
}
|
||||
|
||||
if (MainSettingsManager.getSharedFolder(activity) && MainSettingsManager.getArch(activity).equals("I386")) {
|
||||
Toast.makeText(activity, R.string.shared_folder_is_not_used_because_i386_does_not_support_it, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
if (MainSettingsManager.getVncExternal(activity) &&
|
||||
NetworkUtils.isPortOpen("localhost", Config.defaultVNCPort + Config.defaultVNCPort, 500)) {
|
||||
DialogUtils.twoDialog(activity, activity.getString(R.string.problem_has_been_detected),
|
||||
activity.getString(R.string.the_vnc_server_port_you_set_is_currently_in_use_by_other),
|
||||
activity.getString(R.string.go_to_settings),
|
||||
activity.getString(R.string.close),
|
||||
true, R.drawable.warning_48px, true,
|
||||
() -> activity.startActivity(new Intent(activity, VNCActivity.class)),
|
||||
null,
|
||||
null);
|
||||
return;
|
||||
}
|
||||
|
||||
showProgressDialog(activity, activity.getString(R.string.booting_up));
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(
|
||||
() -> {
|
||||
if (ServiceUtils.isServiceRunning(activity, MainService.class)) {
|
||||
MainService.startCommand(env, activity);
|
||||
} else {
|
||||
Intent serviceIntent = new Intent(activity, MainService.class);
|
||||
MainService.env = env;
|
||||
MainService.CHANNEL_ID = vmName;
|
||||
MainService.activity = activity;
|
||||
if (SDK_INT >= Build.VERSION_CODES.O) {
|
||||
activity.startForegroundService(serviceIntent);
|
||||
} else {
|
||||
activity.startService(serviceIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (MainSettingsManager.getVmUi(activity).equals("VNC")) {
|
||||
if (MainSettingsManager.getVncExternal(activity)) {
|
||||
if (extVncLayout != null) extVncLayout.setVisibility(View.VISIBLE);
|
||||
if (appbar != null) appbar.setExpanded(true);
|
||||
progressDialog.dismiss();
|
||||
} else {
|
||||
Handler handler1 = new Handler();
|
||||
handler1.postDelayed(
|
||||
() -> {
|
||||
MainVNCActivity.started = true;
|
||||
activity.startActivity(
|
||||
new Intent(
|
||||
activity, MainVNCActivity.class));
|
||||
progressDialog.dismiss();
|
||||
},
|
||||
2000);
|
||||
}
|
||||
// } else if (MainSettingsManager.getVmUi(activity).equals("SPICE")) {
|
||||
// //This feature is not available yet.
|
||||
} else if (MainSettingsManager.getVmUi(activity).equals("X11")) {
|
||||
Handler handler1 = new Handler();
|
||||
handler1.postDelayed(
|
||||
() -> {
|
||||
progressDialog.dismiss();
|
||||
DisplaySystem.launchX11(activity, false);
|
||||
},
|
||||
3000);
|
||||
}
|
||||
|
||||
if (MainSettingsManager.getVncExternal(activity)) {
|
||||
Config.currentVNCServervmID = Config.vmID;
|
||||
DialogUtils.oneDialog(activity, activity.getString(R.string.vnc_server), activity.getString(R.string.running_vm_with_vnc_server_content) + " " + (Integer.parseInt(MainSettingsManager.getVncExternalDisplay(activity)) + 5900) + ".", activity.getString(R.string.ok), true, R.drawable.cast_24px, true, null, null);
|
||||
}
|
||||
},
|
||||
2000);
|
||||
String[] params = env.split("\\s+");
|
||||
VectrasStatus.logInfo("Params:");
|
||||
Log.d("HomeStartVM", "Params:");
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
VectrasStatus.logInfo(i + ": " + params[i]);
|
||||
Log.d("HomeStartVM", i + ": " + params[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void showProgressDialog(Activity activity, String _content) {
|
||||
View progressView = LayoutInflater.from(activity).inflate(R.layout.dialog_progress_style, null);
|
||||
TextView progress_text = progressView.findViewById(R.id.progress_text);
|
||||
progress_text.setText(_content);
|
||||
progressDialog = new MaterialAlertDialogBuilder(activity, R.style.CenteredDialogTheme)
|
||||
.setView(progressView)
|
||||
.setCancelable(false)
|
||||
.create();
|
||||
|
||||
progressDialog.show();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.vectras.vm.home.core;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.StartVM;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vterm.Terminal;
|
||||
|
||||
public class PendingCommand {
|
||||
public static void runNow(Activity activity) {
|
||||
if (!AppConfig.pendingCommand.isEmpty()) {
|
||||
if (!VMManager.isthiscommandsafe(AppConfig.pendingCommand, activity)) {
|
||||
AppConfig.pendingCommand = "";
|
||||
DialogUtils.oneDialog(
|
||||
activity,
|
||||
activity.getString(R.string.problem_has_been_detected),
|
||||
activity.getString(R.string.harmful_command_was_detected) + " " + activity.getResources().getString(R.string.reason) + ": " + VMManager.latestUnsafeCommandReason,
|
||||
activity.getString(R.string.ok),
|
||||
true,
|
||||
R.drawable.verified_user_24px,
|
||||
true,
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
if (AppConfig.pendingCommand.startsWith("qemu-img")) {
|
||||
if (!VMManager.isthiscommandsafeimg(AppConfig.pendingCommand, activity)) {
|
||||
DialogUtils.oneDialog(activity,
|
||||
activity.getString(R.string.problem_has_been_detected),
|
||||
activity.getString(R.string.size_too_large_try_qcow2_format),
|
||||
activity.getString(R.string.ok),
|
||||
true,
|
||||
R.drawable.warning_48px,
|
||||
true,
|
||||
null,
|
||||
null
|
||||
);
|
||||
} else {
|
||||
Terminal _vterm = new Terminal(activity);
|
||||
_vterm.executeShellCommand2(AppConfig.pendingCommand, false, activity);
|
||||
Toast.makeText(activity, activity.getResources().getString(R.string.done), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
} else {
|
||||
com.vectras.vm.StartVM.cdrompath = "";
|
||||
String env = StartVM.env(activity, AppConfig.pendingCommand, "", "1");
|
||||
HomeStartVM.startNow(activity, "Quick run", env, AppConfig.pendingCommand, "", null, null);
|
||||
VMManager.lastQemuCommand = AppConfig.pendingCommand;
|
||||
}
|
||||
}
|
||||
AppConfig.pendingCommand = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.vectras.vm.home.core;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.vectras.vm.CustomRomActivity;
|
||||
import com.vectras.vm.ExportRomActivity;
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.VMManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RomOptionsDialog {
|
||||
public static void showNow(Activity activity, List<DataMainRoms> data, int position, String vmID, String vmName, String arch) {
|
||||
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(activity);
|
||||
View v = activity.getLayoutInflater().inflate(R.layout.rom_options_dialog, null);
|
||||
bottomSheetDialog.setContentView(v);
|
||||
|
||||
Button modifyRomBtn = v.findViewById(R.id.modifyRomBtn);
|
||||
modifyRomBtn.setOnClickListener(v3 -> {
|
||||
CustomRomActivity.current = data.get(position);
|
||||
VMManager.setArch(arch, activity);
|
||||
activity.startActivity(new Intent(activity, CustomRomActivity.class).putExtra("POS", position).putExtra("MODIFY", true).putExtra("VMID", vmID));
|
||||
bottomSheetDialog.cancel();
|
||||
});
|
||||
|
||||
Button exportRomBtn = v.findViewById(R.id.exportRomBtn);
|
||||
exportRomBtn.setOnClickListener(v2 -> {
|
||||
ExportRomActivity.pendingPosition = position;
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(activity, ExportRomActivity.class);
|
||||
activity.startActivity(intent);
|
||||
bottomSheetDialog.cancel();
|
||||
});
|
||||
|
||||
Button removeRomBtn = v.findViewById(R.id.removeRomBtn);
|
||||
removeRomBtn.setOnClickListener(v1 -> {
|
||||
VMManager.deleteVMDialog(vmName, position, activity);
|
||||
bottomSheetDialog.cancel();
|
||||
});
|
||||
bottomSheetDialog.show();
|
||||
}
|
||||
}
|
||||
10
app/src/main/java/com/vectras/vm/home/core/SharedData.java
Normal file
10
app/src/main/java/com/vectras/vm/home/core/SharedData.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package com.vectras.vm.home.core;
|
||||
|
||||
import com.vectras.vm.Roms.DataRoms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SharedData {
|
||||
public static List<DataRoms> dataRomStore = new ArrayList<>();
|
||||
}
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
package com.vectras.vm.home.monitor;
|
||||
|
||||
import static android.content.Context.ACTIVITY_SERVICE;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.StatFs;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.google.android.material.transition.MaterialFadeThrough;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.databinding.FragmentHomeSystemMonitorBinding;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vterm.Terminal;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SystemMonitorFragment extends Fragment {
|
||||
final String TAG = "SystemMonitorFragment";
|
||||
FragmentHomeSystemMonitorBinding binding;
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
boolean isStopUpdateMonitor = false;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setEnterTransition(new MaterialFadeThrough());
|
||||
setReturnTransition(new MaterialFadeThrough());
|
||||
setExitTransition(new MaterialFadeThrough());
|
||||
setReenterTransition(new MaterialFadeThrough());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentHomeSystemMonitorBinding.inflate(getLayoutInflater());
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
startMonitor();
|
||||
getQemuInfo();
|
||||
initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if(isStopUpdateMonitor) {
|
||||
startMonitor();
|
||||
getQemuInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
stopMonitor();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
binding.btStopqemu.setOnClickListener(v -> VMManager.requestKillAllQemuProcess(requireActivity(), () -> {
|
||||
ScheduledExecutorService executorUpdate = Executors.newSingleThreadScheduledExecutor();
|
||||
executorUpdate.schedule(() -> {
|
||||
if (getContext() != null) {
|
||||
requireActivity().runOnUiThread(this::getQemuInfo);
|
||||
}
|
||||
}, 500, TimeUnit.MILLISECONDS);
|
||||
}));
|
||||
|
||||
binding.btStopvmvnc.setOnClickListener(v -> {
|
||||
if (Config.currentVNCServervmID.isEmpty()) {
|
||||
binding.btStopvmvnc.setVisibility(View.GONE);
|
||||
} else {
|
||||
DialogUtils.threeDialog(
|
||||
requireActivity(),
|
||||
getString(R.string.shutdown),
|
||||
getString(R.string.shutdown_or_reset_content),
|
||||
getString(R.string.shutdown),
|
||||
getString(R.string.cancel),
|
||||
getString(R.string.reset),
|
||||
true,
|
||||
R.drawable.power_settings_new_24px,
|
||||
true,
|
||||
() -> {
|
||||
Config.vmID = Config.currentVNCServervmID;
|
||||
VMManager.shutdownCurrentVM();
|
||||
Config.currentVNCServervmID = "";
|
||||
binding.btStopvmvnc.setVisibility(View.GONE);
|
||||
getQemuInfo();
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
Config.vmID = Config.currentVNCServervmID;
|
||||
VMManager.resetCurrentVM();
|
||||
},
|
||||
null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final Handler handler = new Handler(Looper.getMainLooper());
|
||||
private final Runnable monitorTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isStopUpdateMonitor) return;
|
||||
updateSystemMonitor();
|
||||
handler.postDelayed(this, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
private void startMonitor() {
|
||||
isStopUpdateMonitor = false;
|
||||
handler.post(monitorTask);
|
||||
}
|
||||
|
||||
private void stopMonitor() {
|
||||
isStopUpdateMonitor = true;
|
||||
handler.removeCallbacks(monitorTask);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void updateSystemMonitor() {
|
||||
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
|
||||
ActivityManager activityManager = (ActivityManager) requireActivity().getSystemService(ACTIVITY_SERVICE);
|
||||
activityManager.getMemoryInfo(mi);
|
||||
|
||||
double totalMemory = mi.totalMem * Math.pow(10, -9);
|
||||
double freeMemory = mi.availMem * Math.pow(10, -9);
|
||||
double usedMemory = totalMemory - freeMemory;
|
||||
double percentageOfRam = (100 / totalMemory) * usedMemory;
|
||||
|
||||
binding.tvTotalram.setText(getString(R.string.total_memory) + " " + String.format(Locale.US, "%.1f", totalMemory) + " GB");
|
||||
binding.tvUsedram.setText(getString(R.string.used_memory) + " " + String.format(Locale.US, "%.1f", usedMemory) + " GB");
|
||||
binding.tvPercentageofram.setText((int) percentageOfRam + "%");
|
||||
if (SDK_INT >= Build.VERSION_CODES.N) {
|
||||
binding.cpiMemory.setProgress((int) percentageOfRam, true);
|
||||
} else {
|
||||
binding.cpiMemory.setProgress((int) percentageOfRam);
|
||||
}
|
||||
|
||||
|
||||
StatFs externalStatFs = new StatFs( Environment.getExternalStorageDirectory().getAbsolutePath() );
|
||||
|
||||
double totalStorage = (externalStatFs.getBlockCountLong() * externalStatFs.getBlockSizeLong()) * Math.pow(10, -9);
|
||||
double freeStorage = (externalStatFs.getAvailableBlocksLong() * externalStatFs.getBlockSizeLong()) * Math.pow(10, -9);
|
||||
double usedStorage = totalStorage - freeStorage;
|
||||
double percentageOfStorage = (100 / totalStorage) * usedStorage;
|
||||
|
||||
binding.tvTotalstorage.setText(getString(R.string.total_memory) + " " + String.format(Locale.US, "%.1f", totalStorage) + " GB");
|
||||
binding.tvUsedstorage.setText(getString(R.string.used_memory) + " " + String.format(Locale.US, "%.1f", usedStorage) + " GB");
|
||||
binding.tvPercentageofstorage.setText((int) percentageOfStorage + "%");
|
||||
if (SDK_INT >= Build.VERSION_CODES.N) {
|
||||
binding.cpiStorage.setProgress((int) percentageOfStorage, true);
|
||||
} else {
|
||||
binding.cpiStorage.setProgress((int) percentageOfStorage);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void getQemuInfo() {
|
||||
String currentArch = MainSettingsManager.getArch(requireActivity());
|
||||
String command = "qemu-system-x86_64 --version";
|
||||
new Terminal(requireActivity()).extractQemuVersion(command, false, requireActivity(), (output, errors) -> {
|
||||
if (errors.isEmpty()) {
|
||||
binding.tvQemuversion.setText(getString(R.string.version) + " " + (output.equals("8.2.1") ? output + " - 3dfx" : getString(R.string.unknow)) + ".");
|
||||
} else {
|
||||
Log.e(TAG, "Errors: " + errors);
|
||||
}
|
||||
});
|
||||
|
||||
binding.tvQemuarch.setText(getString(R.string.arch) + " " + currentArch + ".");
|
||||
|
||||
executor.execute(() -> {
|
||||
String result = Terminal.executeShellCommandWithResult("ps -e", requireActivity());
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
if (!result.isEmpty()) {
|
||||
switch (currentArch) {
|
||||
case "X86_64" ->
|
||||
binding.tvQemustatus.setText(getString(R.string.status_qemu) + " " + (result.contains("qemu-system-x86_64 -qmp") ? getString(R.string.running) : getString(R.string.stopped)) + ".");
|
||||
case "I386" ->
|
||||
binding.tvQemustatus.setText(getString(R.string.status_qemu) + " " + (result.contains("qemu-system-i386 -qmp") ? getString(R.string.running) : getString(R.string.stopped)) + ".");
|
||||
case "ARM64" ->
|
||||
binding.tvQemustatus.setText(getString(R.string.status_qemu) + " " + (result.contains("qemu-system-aarch64 -qmp") ? getString(R.string.running) : getString(R.string.stopped)) + ".");
|
||||
case "PPC" ->
|
||||
binding.tvQemustatus.setText(getString(R.string.status_qemu) + " " + (result.contains("qemu-system-ppc -qmp") ? getString(R.string.running) : getString(R.string.stopped)) + ".");
|
||||
default -> binding.tvQemustatus.setText(getString(R.string.status_qemu) + " " + getString(R.string.stopped) + ".");
|
||||
}
|
||||
|
||||
if (result.contains("qemu-system") && result.contains("-qmp")) {
|
||||
binding.btStopqemu.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.btStopqemu.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
binding.tvQemustatus.setText(getString(R.string.status_qemu) + " " + getString(R.string.stopped) + ".");
|
||||
binding.btStopqemu.setVisibility(View.GONE);
|
||||
Log.i(TAG, "Errors: " + result);
|
||||
}
|
||||
|
||||
getVNCServerStatus(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void getVNCServerStatus(String resultCommand) {
|
||||
binding.tvVncport.setText(getString(R.string.port_qemu) + " " + (Integer.parseInt(MainSettingsManager.getVncExternalDisplay(requireActivity())) + 5900) + ".");
|
||||
|
||||
if (resultCommand.contains(Config.defaultVNCHost + ":" + Config.defaultVNCPort)) {
|
||||
binding.tvVncstatus.setText(getString(R.string.status_qemu) + " " + getString(R.string.running) + ".");
|
||||
binding.btStopvmvnc.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.tvVncstatus.setText(getString(R.string.status_qemu) + " " + getString(R.string.stopped) + ".");
|
||||
binding.btStopvmvnc.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.vectras.vm.home.romstore;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.vectras.vm.Roms.DataRoms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HomeRomStoreViewModel extends ViewModel {
|
||||
private final MutableLiveData<List<DataRoms>> romsList = new MutableLiveData<>(new ArrayList<>());
|
||||
|
||||
public LiveData<List<DataRoms>> getRomsList() {
|
||||
return romsList;
|
||||
}
|
||||
|
||||
public void setRomsList(List<DataRoms> data) {
|
||||
romsList.setValue(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
package com.vectras.vm.home.romstore;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.google.android.material.transition.MaterialFadeThrough;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.RequestNetwork;
|
||||
import com.vectras.vm.RequestNetworkController;
|
||||
import com.vectras.vm.Roms.AdapterRoms;
|
||||
import com.vectras.vm.Roms.DataRoms;
|
||||
import com.vectras.vm.databinding.FragmentHomeRomStoreBinding;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.home.core.SharedData;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class RomStoreFragment extends Fragment {
|
||||
|
||||
FragmentHomeRomStoreBinding binding;
|
||||
private RequestNetwork net;
|
||||
private RequestNetwork.RequestListener _net_request_listener;
|
||||
private String contentJSON = "[]";
|
||||
HomeRomStoreViewModel homeRomStoreViewModel;
|
||||
RomStoreHomeAdpater mAdapter;
|
||||
List<DataRoms> data = new ArrayList<>();
|
||||
|
||||
public static RomStoreCallToHomeListener romStoreCallToHomeListener;
|
||||
public interface RomStoreCallToHomeListener {
|
||||
void updateDataStatus(boolean isReady);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setEnterTransition(new MaterialFadeThrough());
|
||||
setReturnTransition(new MaterialFadeThrough());
|
||||
setExitTransition(new MaterialFadeThrough());
|
||||
setReenterTransition(new MaterialFadeThrough());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentHomeRomStoreBinding.inflate(inflater, container, false);
|
||||
return binding.getRoot();
|
||||
}
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
mAdapter = new RomStoreHomeAdpater(getContext(), data);
|
||||
binding.rvRomlist.setAdapter(mAdapter);
|
||||
binding.rvRomlist.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
||||
|
||||
homeRomStoreViewModel = new ViewModelProvider(requireActivity()).get(HomeRomStoreViewModel.class);
|
||||
homeRomStoreViewModel.getRomsList().observe(getViewLifecycleOwner(), roms -> {
|
||||
if (roms == null || roms.isEmpty()) {
|
||||
loadFromServer();
|
||||
} else {
|
||||
binding.linearload.setVisibility(View.GONE);
|
||||
data.clear();
|
||||
data.addAll(roms);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadFromServer() {
|
||||
romStoreCallToHomeListener.updateDataStatus(false);
|
||||
|
||||
net = new RequestNetwork(requireActivity());
|
||||
_net_request_listener = new RequestNetwork.RequestListener() {
|
||||
@Override
|
||||
public void onResponse(String tag, String response, HashMap<String, Object> responseHeaders) {
|
||||
if (!response.isEmpty())
|
||||
contentJSON = response;
|
||||
loadData();
|
||||
binding.linearload.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onErrorResponse(String tag, String message) {
|
||||
binding.linearload.setVisibility(View.GONE);
|
||||
binding.linearnothinghere.setVisibility(View.VISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
binding.buttontryagain.setOnClickListener(v -> {
|
||||
binding.linearload.setVisibility(View.VISIBLE);
|
||||
net.startRequestNetwork(RequestNetworkController.GET,AppConfig.vectrasRaw + "vroms-store.json","",_net_request_listener);
|
||||
});
|
||||
|
||||
net.startRequestNetwork(RequestNetworkController.GET, AppConfig.vectrasRaw + "vroms-store.json","",_net_request_listener);
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
List<DataRoms> dataRoms = new ArrayList<>();
|
||||
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
Type listType = new TypeToken<List<DataRoms>>() {}.getType();
|
||||
dataRoms = gson.fromJson(contentJSON, listType);
|
||||
} catch (Exception e) {
|
||||
binding.linearload.setVisibility(View.GONE);
|
||||
binding.linearnothinghere.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
homeRomStoreViewModel.setRomsList(dataRoms);
|
||||
data.clear();
|
||||
data.addAll(dataRoms);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
SharedData.dataRomStore.addAll(dataRoms);
|
||||
romStoreCallToHomeListener.updateDataStatus(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package com.vectras.vm.home.romstore;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RomInfo;
|
||||
import com.vectras.vm.Roms.DataRoms;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RomStoreHomeAdpater extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
Context context;
|
||||
private final LayoutInflater inflater;
|
||||
static List<DataRoms> dataRom = Collections.emptyList();
|
||||
|
||||
public RomStoreHomeAdpater(Context context, List<DataRoms> data) {
|
||||
this.context = context;
|
||||
inflater = LayoutInflater.from(context);
|
||||
dataRom = data;
|
||||
}
|
||||
|
||||
// Inflate the layout when viewholder created
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = inflater.inflate(R.layout.container_roms, parent, false);
|
||||
return new MyHolder(view);
|
||||
}
|
||||
|
||||
// Bind data
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
|
||||
|
||||
// Get current position of item in recyclerview to bind data and assign values from list
|
||||
final MyHolder myHolder = (MyHolder) holder;
|
||||
final DataRoms current = dataRom.get(position);
|
||||
Glide.with(context).load(current.romIcon).placeholder(R.drawable.ic_computer_180dp_with_padding).error(R.drawable.ic_computer_180dp_with_padding).into(myHolder.ivIcon);
|
||||
myHolder.textName.setText(current.romName);
|
||||
myHolder.textSize.setText(current.romArch + " - " + current.fileSize);
|
||||
if (current.romAvail) {
|
||||
myHolder.linearItem.setOnClickListener(v -> {
|
||||
notifyItemRangeChanged(0, dataRom.size());
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setClass(context, RomInfo.class);
|
||||
intent.putExtra("title", current.romName);
|
||||
intent.putExtra("shortdesc", current.romSize);
|
||||
intent.putExtra("getrom", current.romUrl);
|
||||
intent.putExtra("desc", current.desc);
|
||||
intent.putExtra("icon", current.romIcon);
|
||||
intent.putExtra("filename", current.romPath);
|
||||
intent.putExtra("finalromfilename", current.finalromfilename);
|
||||
intent.putExtra("extra", current.romExtra);
|
||||
intent.putExtra("arch", current.romArch);
|
||||
intent.putExtra("verified", current.verified);
|
||||
intent.putExtra("creator", current.creator);
|
||||
intent.putExtra("size", current.fileSize);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
} else {
|
||||
myHolder.textAvail.setText(context.getString(R.string.unavailable));
|
||||
myHolder.textAvail.setTextColor(Color.RED);
|
||||
}
|
||||
|
||||
if (dataRom.size() == 1) {
|
||||
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_single));
|
||||
} else if (position == 0) {
|
||||
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_top));
|
||||
} else if (position == dataRom.size() - 1) {
|
||||
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_bottom));
|
||||
} else {
|
||||
myHolder.linearItem.setBackground(AppCompatResources.getDrawable(context, R.drawable.object_shape_middle));
|
||||
}
|
||||
}
|
||||
|
||||
// return total item from List
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataRom == null ? 0 : dataRom.size();
|
||||
}
|
||||
|
||||
static class MyHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView textName, textAvail, textSize;
|
||||
ImageView ivIcon;
|
||||
LinearLayout linearItem;
|
||||
|
||||
// create constructor to get widget reference
|
||||
public MyHolder(View itemView) {
|
||||
super(itemView);
|
||||
textName = itemView.findViewById(R.id.textName);
|
||||
ivIcon = itemView.findViewById(R.id.ivIcon);
|
||||
textSize = itemView.findViewById(R.id.textSize);
|
||||
textAvail = itemView.findViewById(R.id.textAvail);
|
||||
|
||||
linearItem = itemView.findViewById(R.id.linearItem);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
42
app/src/main/java/com/vectras/vm/home/vms/VmsDiffUtil.java
Normal file
42
app/src/main/java/com/vectras/vm/home/vms/VmsDiffUtil.java
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package com.vectras.vm.home.vms;
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VmsDiffUtil extends DiffUtil.Callback {
|
||||
private final List<DataMainRoms> oldList;
|
||||
private final List<DataMainRoms> newList;
|
||||
|
||||
public VmsDiffUtil(List<DataMainRoms> oldList, List<DataMainRoms> newList) {
|
||||
this.oldList = oldList;
|
||||
this.newList = newList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOldListSize() {
|
||||
return oldList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNewListSize() {
|
||||
return newList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
// So sánh bằng khóa duy nhất (vd: vmID)
|
||||
return oldList.get(oldItemPosition).vmID.equals(newList.get(newItemPosition).vmID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
|
||||
// So sánh nội dung, nếu khác thì update item đó
|
||||
DataMainRoms oldItem = oldList.get(oldItemPosition);
|
||||
DataMainRoms newItem = newList.get(newItemPosition);
|
||||
return oldItem.equals(newItem); // Nếu bạn override equals trong DataMainRoms thì dùng cách này
|
||||
}
|
||||
}
|
||||
|
||||
199
app/src/main/java/com/vectras/vm/home/vms/VmsFragment.java
Normal file
199
app/src/main/java/com/vectras/vm/home/vms/VmsFragment.java
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
package com.vectras.vm.home.vms;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.google.android.material.transition.MaterialFadeThrough;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.databinding.FragmentHomeVmsBinding;
|
||||
import com.vectras.vm.home.HomeActivity;
|
||||
import com.vectras.vm.home.core.CallbackInterface;
|
||||
import com.vectras.vm.utils.DeviceUtils;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.PermissionUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class VmsFragment extends Fragment implements CallbackInterface.HomeCallToVmsListener {
|
||||
private final String TAG = "VmsFragment";
|
||||
FragmentHomeVmsBinding binding;
|
||||
private JSONArray jArray;
|
||||
private final List<DataMainRoms> data = new ArrayList<>();
|
||||
private VmsHomeAdapter vmsHomeAdapter;
|
||||
private int spanCount = 0;
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
public static VmsCallToHomeListener vmsCallToHomeListener;
|
||||
public interface VmsCallToHomeListener {
|
||||
void openRomStore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setEnterTransition(new MaterialFadeThrough());
|
||||
setReturnTransition(new MaterialFadeThrough());
|
||||
setExitTransition(new MaterialFadeThrough());
|
||||
setReenterTransition(new MaterialFadeThrough());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
checkAndLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentHomeVmsBinding.inflate(inflater, container, false);
|
||||
spanCount = requireActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2;
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
HomeActivity.homeCallToVmsListener = this;
|
||||
|
||||
binding.rvRomlist.setLayoutManager(new GridLayoutManager(getContext(), spanCount));
|
||||
vmsHomeAdapter = new VmsHomeAdapter(requireActivity(), data);
|
||||
binding.rvRomlist.setAdapter(vmsHomeAdapter);
|
||||
|
||||
binding.bnRomstore.setOnClickListener(v -> {
|
||||
vmsCallToHomeListener.openRomStore();
|
||||
});
|
||||
|
||||
binding.bnRepair.setOnClickListener(V -> {
|
||||
VMManager.startFixRomsDataJson();
|
||||
VMManager.fixRomsDataJsonResult(requireActivity());
|
||||
});
|
||||
|
||||
binding.wrlRomlist.setOnRefreshListener(() -> {
|
||||
checkAndLoad();
|
||||
binding.wrlRomlist.setRefreshing(false);
|
||||
});
|
||||
|
||||
checkAndLoad();
|
||||
}
|
||||
|
||||
private void loadDataVbi() {
|
||||
|
||||
if (!FileUtils.isFileExists(AppConfig.romsdatajson))
|
||||
FileUtils.writeToFile(AppConfig.maindirpath, "roms-data.json", "[]");
|
||||
|
||||
executor.execute(() -> {
|
||||
List<DataMainRoms> tempdata = new ArrayList<>();
|
||||
|
||||
try {
|
||||
jArray = new JSONArray(FileUtils.readFromFile(requireActivity(), new File(AppConfig.maindirpath
|
||||
+ "roms-data.json")));
|
||||
|
||||
// Extract data from json and store into ArrayList as class objects
|
||||
for (int i = 0; i < jArray.length(); i++) {
|
||||
JSONObject json_data = jArray.getJSONObject(i);
|
||||
DataMainRoms romsMainData = new DataMainRoms();
|
||||
romsMainData.itemName = json_data.getString("imgName");
|
||||
romsMainData.itemIcon = json_data.getString("imgIcon");
|
||||
try {
|
||||
romsMainData.itemArch = json_data.getString("imgArch");
|
||||
} catch (JSONException ignored) {
|
||||
romsMainData.itemArch = "unknown";
|
||||
}
|
||||
romsMainData.itemPath = json_data.getString("imgPath");
|
||||
try {
|
||||
romsMainData.imgCdrom = json_data.getString("imgCdrom");
|
||||
} catch (JSONException ignored) {
|
||||
romsMainData.imgCdrom = "";
|
||||
}
|
||||
try {
|
||||
romsMainData.vmID = json_data.getString("vmID");
|
||||
} catch (JSONException ignored) {
|
||||
romsMainData.vmID = "";
|
||||
}
|
||||
try {
|
||||
romsMainData.qmpPort = json_data.getInt("qmpPort");
|
||||
} catch (JSONException ignored) {
|
||||
romsMainData.qmpPort = 0;
|
||||
}
|
||||
try {
|
||||
romsMainData.itemDrv1 = json_data.getString("imgDrv1");
|
||||
} catch (JSONException ignored) {
|
||||
romsMainData.itemDrv1 = "";
|
||||
}
|
||||
romsMainData.itemExtra = json_data.getString("imgExtra");
|
||||
tempdata.add(romsMainData);
|
||||
}
|
||||
requireActivity().runOnUiThread(() -> binding.lnError.setVisibility(View.GONE));
|
||||
} catch (JSONException e) {
|
||||
requireActivity().runOnUiThread(() -> binding.lnError.setVisibility(View.VISIBLE));
|
||||
Log.e(TAG, "loadDataVbi: ", e);
|
||||
}
|
||||
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
binding.lnLoad.setVisibility(View.GONE);
|
||||
if (tempdata.isEmpty()) {
|
||||
binding.lnNothinghere.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.lnNothinghere.setVisibility(View.GONE);
|
||||
vmsHomeAdapter.updateData(tempdata);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void checkAndLoad() {
|
||||
if (PermissionUtils.storagepermission(requireActivity(), true)) {
|
||||
loadDataVbi();
|
||||
if (DeviceUtils.isStorageLow(requireActivity())) {
|
||||
DialogUtils.oneDialog(requireActivity(),
|
||||
getResources().getString(R.string.oops),
|
||||
getResources().getString(R.string.very_low_available_storage_space_content),
|
||||
getResources().getString(R.string.ok),
|
||||
true,
|
||||
R.drawable.warning_48px,
|
||||
true,
|
||||
null,
|
||||
() -> {
|
||||
if (DeviceUtils.isStorageLow(requireActivity()))
|
||||
requireActivity().finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refeshVMList() {
|
||||
requireActivity().runOnUiThread(this::checkAndLoad);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configurationChanged(boolean isLandscape) {
|
||||
spanCount = isLandscape ? 3 : 2;
|
||||
binding.rvRomlist.setLayoutManager(new GridLayoutManager(getContext(), spanCount));
|
||||
}
|
||||
}
|
||||
119
app/src/main/java/com/vectras/vm/home/vms/VmsHomeAdapter.java
Normal file
119
app/src/main/java/com/vectras/vm/home/vms/VmsHomeAdapter.java
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
package com.vectras.vm.home.vms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.vm.MainRoms.DataMainRoms;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.StartVM;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.home.core.HomeStartVM;
|
||||
import com.vectras.vm.home.core.RomOptionsDialog;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class VmsHomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
|
||||
private final Activity activity;
|
||||
private final LayoutInflater inflater;
|
||||
public List<DataMainRoms> data = Collections.emptyList();
|
||||
|
||||
public VmsHomeAdapter(Activity activity, List<DataMainRoms> data) {
|
||||
this.activity = activity;
|
||||
inflater = LayoutInflater.from(activity);
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
// Inflate the layout when viewholder created
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = inflater.inflate(R.layout.container_main_roms, parent, false);
|
||||
return new MyHolder(view);
|
||||
}
|
||||
|
||||
// Bind data
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int _position) {
|
||||
|
||||
int position = holder.getBindingAdapterPosition();
|
||||
if (position == RecyclerView.NO_POSITION) return;
|
||||
|
||||
// Get current position of item in recyclerview to bind data and assign values from list
|
||||
final MyHolder myHolder = (MyHolder) holder;
|
||||
final DataMainRoms current = data.get(position);
|
||||
myHolder.textName.setText(current.itemName);
|
||||
myHolder.textArch.setText(current.itemArch);
|
||||
if (current.itemIcon.isEmpty()){
|
||||
VMManager.setIconWithName(myHolder.ivIcon, current.itemName);
|
||||
} else {
|
||||
Bitmap bmImg = BitmapFactory.decodeFile(current.itemIcon);
|
||||
myHolder.ivIcon.setImageBitmap(bmImg);
|
||||
}
|
||||
myHolder.optionsBtn.setOnClickListener(view -> RomOptionsDialog.showNow(activity, data, position, current.vmID, current.itemName, current.itemArch));
|
||||
|
||||
myHolder.cdRoms.setOnClickListener(view -> {
|
||||
VMManager.setArch(current.itemArch, activity);
|
||||
StartVM.cdrompath = current.imgCdrom;
|
||||
if (current.qmpPort == 0) {
|
||||
Config.setDefault();
|
||||
} else {
|
||||
Config.QMPPort = current.qmpPort;
|
||||
}
|
||||
Config.vmID = current.vmID;
|
||||
String env = StartVM.env(activity, current.itemExtra, current.itemPath, "");
|
||||
HomeStartVM.startNow(activity, current.itemName, env, current.itemExtra, current.itemPath, null, null);
|
||||
});
|
||||
|
||||
myHolder.cdRoms.setOnLongClickListener(v -> {
|
||||
VMManager.deleteVMDialog(current.itemName, position, activity);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// return total item from List
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
static class MyHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
CardView cdRoms;
|
||||
TextView textName, textArch;
|
||||
ImageView ivIcon;
|
||||
ImageButton optionsBtn;
|
||||
|
||||
// create constructor to get widget reference
|
||||
public MyHolder(View itemView) {
|
||||
super(itemView);
|
||||
cdRoms = itemView.findViewById(R.id.cdItem);
|
||||
textName = itemView.findViewById(R.id.textName);
|
||||
textArch = itemView.findViewById(R.id.textArch);
|
||||
ivIcon = itemView.findViewById(R.id.ivIcon);
|
||||
optionsBtn = itemView.findViewById(R.id.optionsButton);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateData(List<DataMainRoms> newData) {
|
||||
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new VmsDiffUtil(this.data, newData));
|
||||
this.data.clear();
|
||||
this.data.addAll(newData);
|
||||
diffResult.dispatchUpdatesTo(this);
|
||||
}
|
||||
|
||||
}
|
||||
162
app/src/main/java/com/vectras/vm/settings/UpdaterActivity.java
Normal file
162
app/src/main/java/com/vectras/vm/settings/UpdaterActivity.java
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
package com.vectras.vm.settings;
|
||||
|
||||
import static android.content.Intent.ACTION_VIEW;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RequestNetwork;
|
||||
import com.vectras.vm.RequestNetworkController;
|
||||
import com.vectras.vm.databinding.ActivityUpdaterBinding;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.PackageUtils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
public class UpdaterActivity extends AppCompatActivity {
|
||||
|
||||
ActivityUpdaterBinding binding;
|
||||
String downloadUrl = "";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_vncactivity);
|
||||
binding = ActivityUpdaterBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
|
||||
binding.toolbar.setNavigationOnClickListener(view -> finish());
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
binding.bnUpdate.setOnClickListener(v -> {
|
||||
if (downloadUrl.isEmpty()) {
|
||||
finish();
|
||||
} else {
|
||||
startActivity(new Intent(ACTION_VIEW, Uri.parse(downloadUrl)));
|
||||
}
|
||||
});
|
||||
|
||||
check();
|
||||
}
|
||||
|
||||
private void whenUpToDate() {
|
||||
binding.lpiProgressbar.setVisibility(View.GONE);
|
||||
binding.collapsingToolbarLayout.setTitle(getText(R.string.you_are_up_to_date));
|
||||
binding.collapsingToolbarLayout.setSubtitle(PackageUtils.getThisVersionName(getApplicationContext()));
|
||||
binding.bnUpdate.setText(getString(R.string.close));
|
||||
}
|
||||
|
||||
private void checkAgain() {
|
||||
binding.lpiProgressbar.setVisibility(View.VISIBLE);
|
||||
binding.mcvWhatsnew.setVisibility(View.GONE);
|
||||
binding.lnBottombar.setVisibility(View.GONE);
|
||||
binding.collapsingToolbarLayout.setTitle(getText(R.string.checking_for_updates));
|
||||
binding.collapsingToolbarLayout.setSubtitle(getText(R.string.just_a_sec));
|
||||
binding.bnUpdate.setText(getString(R.string.update));
|
||||
downloadUrl = "";
|
||||
check();
|
||||
}
|
||||
|
||||
private void check() {
|
||||
int versionCode = PackageUtils.getThisVersionCode(getApplicationContext());
|
||||
String versionName = PackageUtils.getThisVersionName(getApplicationContext());
|
||||
|
||||
RequestNetwork requestNetwork = new RequestNetwork(this);
|
||||
RequestNetwork.RequestListener requestNetworkListener = new RequestNetwork.RequestListener() {
|
||||
@Override
|
||||
public void onResponse(String tag, String response, HashMap<String, Object> responseHeaders) {
|
||||
binding.lpiProgressbar.setVisibility(View.GONE);
|
||||
binding.lnBottombar.setVisibility(View.VISIBLE);
|
||||
|
||||
if (!response.isEmpty()) {
|
||||
try {
|
||||
final JSONObject obj = new JSONObject(response);
|
||||
String versionNameonUpdate;
|
||||
int versionCodeonUpdate;
|
||||
String whatsnew;
|
||||
String size;
|
||||
String url;
|
||||
|
||||
if (MainSettingsManager.getcheckforupdatesfromthebetachannel(UpdaterActivity.this)) {
|
||||
versionNameonUpdate = obj.getString("versionNameBeta");
|
||||
versionCodeonUpdate = obj.getInt("versionCodeBeta");
|
||||
whatsnew = obj.getString("MessageBeta");
|
||||
size = obj.getString("sizeBeta");
|
||||
url = obj.getString("urlBeta");
|
||||
} else {
|
||||
versionNameonUpdate = obj.getString("versionName");
|
||||
versionCodeonUpdate = obj.getInt("versionCode");
|
||||
whatsnew = obj.getString("Message");
|
||||
size = obj.getString("size");
|
||||
url = obj.getString("url");
|
||||
}
|
||||
|
||||
if (versionCode < versionCodeonUpdate || !versionNameonUpdate.equals(versionName)) {
|
||||
binding.collapsingToolbarLayout.setTitle(getText(R.string.new_update_available));
|
||||
binding.collapsingToolbarLayout.setSubtitle(getString(R.string.whats_new));
|
||||
binding.mcvWhatsnew.setVisibility(View.VISIBLE);
|
||||
binding.tvWhatsnewcontent.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
binding.tvWhatsnewcontent.setText(Html.fromHtml(whatsnew + "<br><br>Update size:<br>" + size));
|
||||
downloadUrl = url;
|
||||
} else {
|
||||
whenUpToDate();
|
||||
}
|
||||
|
||||
if (obj.getString("versionNameBetas").contains(versionName)
|
||||
&& !MainSettingsManager.getcheckforupdatesfromthebetachannel(UpdaterActivity.this)
|
||||
&& !MainSettingsManager.getDontShowAgainJoinBetaUpdateChannelDialog(UpdaterActivity.this)) {
|
||||
Activity activity = UpdaterActivity.this;
|
||||
|
||||
DialogUtils.threeDialog(activity,
|
||||
activity.getResources().getString(R.string.you_are_using_beta_version),
|
||||
activity.getResources().getString(R.string.switch_to_check_for_updates_on_the_Beta_channel_now),
|
||||
activity.getResources().getString(R.string.ok),
|
||||
activity.getResources().getString(R.string.cancel),
|
||||
activity.getResources().getString(R.string.dont_show_again),
|
||||
true,
|
||||
R.drawable.science_24px,
|
||||
true,
|
||||
() -> {
|
||||
MainSettingsManager.setcheckforupdatesfromthebetachannel(activity, true);
|
||||
checkAgain();
|
||||
},
|
||||
null,
|
||||
() -> MainSettingsManager.setDontShowAgainJoinBetaUpdateChannelDialog(activity, true),
|
||||
null);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
whenUpToDate();
|
||||
}
|
||||
} else {
|
||||
whenUpToDate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onErrorResponse(String tag, String message) {
|
||||
whenUpToDate();
|
||||
}
|
||||
};
|
||||
|
||||
requestNetwork.startRequestNetwork(RequestNetworkController.GET,AppConfig.updateJson,"checkupdate",requestNetworkListener);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,4 +59,8 @@ public class DeviceUtils {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean is64bit() {
|
||||
return Build.SUPPORTED_ABIS[0].contains("arm64");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.vectras.vm.utils;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
|
@ -15,7 +14,6 @@ import android.system.ErrnoException;
|
|||
import android.system.Os;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -27,31 +25,21 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.R;
|
||||
|
||||
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.OutputStreamWriter;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
|
@ -486,11 +474,11 @@ public class FileUtils {
|
|||
|
||||
}
|
||||
|
||||
public static String getDataDir() {
|
||||
public static String getDataDir(Context context) {
|
||||
|
||||
String dataDir = MainActivity.activity.getApplicationInfo().dataDir;
|
||||
PackageManager m = MainActivity.activity.getPackageManager();
|
||||
String packageName = MainActivity.activity.getPackageName();
|
||||
String dataDir = context.getApplicationInfo().dataDir;
|
||||
PackageManager m = context.getPackageManager();
|
||||
String packageName = context.getPackageName();
|
||||
Log.v("VMExecutor", "Found packageName: " + packageName);
|
||||
|
||||
if (dataDir == null) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.vectras.vm.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -9,41 +11,17 @@ import java.util.Objects;
|
|||
|
||||
public class JSONUtils {
|
||||
public static boolean isValidFromString(String _content) {
|
||||
ArrayList<HashMap<String, Objects>> mmap = new ArrayList<>();
|
||||
try {
|
||||
mmap.clear();
|
||||
mmap = new Gson().fromJson(_content, new TypeToken<ArrayList<HashMap<String, Object>>>() {
|
||||
}.getType());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMapValidFromString(String _content) {
|
||||
HashMap<String, Object> mmap = new HashMap<>();
|
||||
try {
|
||||
mmap.clear();
|
||||
mmap= new Gson().fromJson(_content, new TypeToken<HashMap<String, Object>>(){}.getType());
|
||||
return true;
|
||||
JsonElement element = JsonParser.parseString(_content);
|
||||
return element != null;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isValidFromFile(String _filepath) {
|
||||
ArrayList<HashMap<String, Objects>> mmap = new ArrayList<>();
|
||||
String contentjson = "";
|
||||
if (FileUtils.isFileExists(_filepath)) {
|
||||
contentjson = FileUtils.readAFile(_filepath);
|
||||
try {
|
||||
mmap.clear();
|
||||
mmap = new Gson().fromJson(contentjson, new TypeToken<ArrayList<HashMap<String, Object>>>() {
|
||||
}.getType());
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return isValidFromString(FileUtils.readAFile(_filepath));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class LibraryChecker {
|
|||
|
||||
public void checkMissingLibraries(Activity activity) {
|
||||
// List of required libraries
|
||||
String[] requiredLibraries = AppConfig.neededPkgs.split(" ");
|
||||
String[] requiredLibraries = DeviceUtils.is64bit() ? AppConfig.neededPkgs.split(" ") : AppConfig.neededPkgs32bit.split(" ");
|
||||
|
||||
// Get the list of installed packages
|
||||
isPackageInstalled(null, (output, errors) -> {
|
||||
|
|
@ -61,7 +61,7 @@ public class LibraryChecker {
|
|||
.setPositiveButton("Install", (dialog, which) -> {
|
||||
// Create the install command
|
||||
String installCommand = "apk add " + missingLibraries.replace("\n", " ");
|
||||
new Terminal(context).executeShellCommand(installCommand, true, activity);
|
||||
new Terminal(context).executeShellCommand(installCommand, true, true, activity);
|
||||
})
|
||||
.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
|
|
@ -81,7 +81,7 @@ public class LibraryChecker {
|
|||
String command = "apk info";
|
||||
|
||||
Terminal terminal = new Terminal(context);
|
||||
terminal.executeShellCommand(command, (Activity) context, (output, errors) -> {
|
||||
terminal.executeShellCommand(command, (Activity) context, false, (output, errors) -> {
|
||||
if (callback != null) {
|
||||
callback.onCommandCompleted(output, errors);
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ public class LibraryChecker {
|
|||
String command = "apk info";
|
||||
|
||||
Terminal terminal = new Terminal(activity);
|
||||
terminal.executeShellCommand(command, activity, (output, errors) -> {
|
||||
terminal.executeShellCommand(command, activity, false, (output, errors) -> {
|
||||
if (callback != null) {
|
||||
callback.onCommandCompleted(output, errors);
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ public class LibraryChecker {
|
|||
.setCancelable(false)
|
||||
.setPositiveButton("Install", (dialog, which) -> {
|
||||
String installCommand = "apk add " + packageName;
|
||||
new Terminal(context).executeShellCommand(installCommand, true, activity);
|
||||
new Terminal(context).executeShellCommand(installCommand, true, true, activity);
|
||||
})
|
||||
.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss())
|
||||
.show();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
package com.vectras.vm.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
|
@ -20,4 +24,26 @@ public class NetworkUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CHECK WHETHER INTERNET CONNECTION IS AVAILABLE OR NOT
|
||||
*/
|
||||
public boolean checkConnection(Context context) {
|
||||
final ConnectivityManager connMgr = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
if (connMgr != null) {
|
||||
NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
|
||||
|
||||
if (activeNetworkInfo != null) { // connected to the internet
|
||||
// connected to the mobile provider's data plan
|
||||
if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
|
||||
// connected to wifi
|
||||
return true;
|
||||
} else
|
||||
return activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package com.vectras.vm.utils;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
|
||||
public class NotificationUtils {
|
||||
public static void clearAll(Context context) {
|
||||
NotificationManager notificationManager = (NotificationManager) context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.cancelAll();
|
||||
}
|
||||
}
|
||||
10
app/src/main/java/com/vectras/vm/utils/NumberUtils.java
Normal file
10
app/src/main/java/com/vectras/vm/utils/NumberUtils.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package com.vectras.vm.utils;
|
||||
|
||||
public class NumberUtils {
|
||||
public static int safeLongToInt(long l) {
|
||||
if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
|
||||
return 0;
|
||||
}
|
||||
return (int) l;
|
||||
}
|
||||
}
|
||||
18
app/src/main/java/com/vectras/vm/utils/ServiceUtils.java
Normal file
18
app/src/main/java/com/vectras/vm/utils/ServiceUtils.java
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package com.vectras.vm.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
|
||||
public class ServiceUtils {
|
||||
public static boolean isServiceRunning(Context context, Class<?> serviceClass) {
|
||||
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
if (manager != null) {
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,6 @@ import android.text.Html;
|
|||
import android.text.InputType;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
|
@ -41,7 +40,6 @@ import android.widget.Toast;
|
|||
import com.vectras.qemu.Config;
|
||||
import com.vectras.qemu.MainSettingsManager;
|
||||
import com.vectras.qemu.utils.FileUtils;
|
||||
import com.vectras.vm.MainActivity;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.logger.VectrasStatus;
|
||||
|
||||
|
|
@ -461,4 +459,44 @@ public class UIUtils {
|
|||
return insets;
|
||||
});
|
||||
}
|
||||
public static void setOnApplyWindowInsetsListenerBottomOnly(View _view) {
|
||||
int originalPaddingLeft = _view.getPaddingLeft();
|
||||
int originalPaddingTop = _view.getPaddingTop();
|
||||
int originalPaddingRight = _view.getPaddingRight();
|
||||
int originalPaddingBottom = _view.getPaddingBottom();
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(_view, (v, insets) -> {
|
||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
|
||||
v.setPadding(originalPaddingLeft, originalPaddingTop, originalPaddingRight, systemBars.bottom + originalPaddingBottom);
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static void setOnApplyWindowInsetsListenerLeftOnly(View _view) {
|
||||
int originalPaddingLeft = _view.getPaddingLeft();
|
||||
int originalPaddingTop = _view.getPaddingTop();
|
||||
int originalPaddingRight = _view.getPaddingRight();
|
||||
int originalPaddingBottom = _view.getPaddingBottom();
|
||||
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(_view, (v, insets) -> {
|
||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
|
||||
v.setPadding(systemBars.left + originalPaddingLeft , originalPaddingTop, originalPaddingRight, originalPaddingBottom);
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
|
||||
public static void setOnApplyWindowInsetsListenerHorizontalOnly(View _view) {
|
||||
int originalPaddingLeft = _view.getPaddingLeft();
|
||||
int originalPaddingTop = _view.getPaddingTop();
|
||||
int originalPaddingRight = _view.getPaddingRight();
|
||||
int originalPaddingBottom = _view.getPaddingBottom();
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(_view, (v, insets) -> {
|
||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
|
||||
v.setPadding(systemBars.left + originalPaddingLeft, originalPaddingTop, systemBars.right + originalPaddingRight, originalPaddingBottom);
|
||||
return insets;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public class JoystickView extends View
|
|||
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when a
|
||||
* CallbackInterface definition for a callback to be invoked when a
|
||||
* JoystickView's button is moved
|
||||
*/
|
||||
public interface OnMoveListener {
|
||||
|
|
@ -43,7 +43,7 @@ public class JoystickView extends View
|
|||
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when a JoystickView
|
||||
* CallbackInterface definition for a callback to be invoked when a JoystickView
|
||||
* is touched and held by multiple pointers.
|
||||
*/
|
||||
public interface OnMultipleLongPressListener {
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ public class RadioGroupPlus extends LinearLayout {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>Interface definition for a callback to be invoked when the checked
|
||||
* <p>CallbackInterface definition for a callback to be invoked when the checked
|
||||
* radio button changed in this group.</p>
|
||||
*/
|
||||
public interface OnCheckedChangeListener {
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ public class X11Activity extends AppCompatActivity implements View.OnApplyWindow
|
|||
// Stop the service
|
||||
MainService.stopService();
|
||||
//Terminal.killQemuProcess();
|
||||
VMManager.killcurrentqemuprocess(getApplicationContext());
|
||||
VMManager.killcurrentqemuprocess(X11Activity.this);
|
||||
finish();
|
||||
})
|
||||
.setNegativeButton(getString(R.string.no), null)
|
||||
|
|
|
|||
|
|
@ -757,7 +757,7 @@ public class TouchInputHandler {
|
|||
|
||||
|
||||
/**
|
||||
* Interface with a set of functions to control the behavior of the remote host renderer.
|
||||
* CallbackInterface with a set of functions to control the behavior of the remote host renderer.
|
||||
*/
|
||||
public interface RenderStub {
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue