mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 12:27:39 +00:00
Update busybox; Improve environment setup
This commit is contained in:
parent
dac85757b3
commit
89932b325d
@ -104,13 +104,13 @@ public class LogFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void reloadErrorLog() {
|
||||
new LogsManager(true).execute();
|
||||
new LogsManager(true).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
svLog.post(() -> svLog.scrollTo(0, txtLog.getHeight()));
|
||||
hsvLog.post(() -> hsvLog.scrollTo(0, 0));
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
new LogsManager(false).execute();
|
||||
new LogsManager(false).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
reloadErrorLog();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class MagiskFragment extends Fragment {
|
||||
ta0.recycle();
|
||||
ta1.recycle();
|
||||
ta2.recycle();
|
||||
new updateUI().execute();
|
||||
new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
|
||||
return v;
|
||||
}
|
||||
@ -132,7 +132,7 @@ public class MagiskFragment extends Fragment {
|
||||
new Utils.DownloadReceiver(getString(R.string.magisk)) {
|
||||
@Override
|
||||
public void task(File file) {
|
||||
new Async.FlashZIP(mContext, mName, file.getPath()).execute();
|
||||
new Async.FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
},
|
||||
Utils.magiskLink, "latest_magisk.zip"))
|
||||
|
@ -12,6 +12,7 @@ import android.preference.PreferenceManager;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
@ -22,6 +23,7 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
import butterknife.BindView;
|
||||
@ -56,13 +58,15 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
setContentView(R.layout.activity_main);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
// Startups
|
||||
Utils.init(this);
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
||||
}
|
||||
|
||||
if (!Shell.rootAccess()) {
|
||||
Snackbar.make(findViewById(android.R.id.content), R.string.no_root_access, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
this.getFragmentManager().addOnBackStackChangedListener(
|
||||
() -> {
|
||||
Fragment hm = getFragmentManager().findFragmentByTag("root");
|
||||
@ -108,7 +112,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
setSupportActionBar(toolbar);
|
||||
@ -149,12 +152,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
@ -5,6 +5,7 @@ import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
@ -110,7 +111,7 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
|
||||
@Override
|
||||
public void task(File file) {
|
||||
Log.d("Magisk", "Task firing");
|
||||
new Async.FlashZIP(context, mModule.getId(), file.toString()).execute();
|
||||
new Async.FlashZIP(context, mModule.getId(), file.toString()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
String filename = mModule.getId().replace(" ", "") + ".zip";
|
||||
|
@ -62,8 +62,8 @@ public class ModulesFragment extends Fragment {
|
||||
mSwipeRefreshLayout.setOnRefreshListener(() -> {
|
||||
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
new Async.LoadModules(getActivity()).execute();
|
||||
new updateUI().execute();
|
||||
new Async.LoadModules(getActivity()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
prefs.edit().putBoolean("ignoreUpdateAlerts", false).apply();
|
||||
|
||||
});
|
||||
@ -76,7 +76,7 @@ public class ModulesFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
new updateUI().execute();
|
||||
new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
|
||||
return viewMain;
|
||||
}
|
||||
@ -88,7 +88,7 @@ public class ModulesFragment extends Fragment {
|
||||
final Uri uri = data.getData();
|
||||
try {
|
||||
// Get the file path from the URI
|
||||
new Async.FlashZIP(getActivity(), uri).execute();
|
||||
new Async.FlashZIP(getActivity(), uri).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
FileInfo fileInfo = FileUtils.getFileInfo(getActivity(), uri);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
@ -6,6 +6,7 @@ import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.DisplayMetrics;
|
||||
@ -148,7 +149,7 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
|
||||
@Override
|
||||
public void task(File file) {
|
||||
Log.d("Magisk", "Task firing");
|
||||
new Async.FlashZIP(context, repo.getId(), file.toString()).execute();
|
||||
new Async.FlashZIP(context, repo.getId(), file.toString()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
String filename = repo.getId().replace(" ", "") + ".zip";
|
||||
|
@ -2,6 +2,7 @@ package com.topjohnwu.magisk;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
@ -126,7 +127,7 @@ public class ReposFragment extends Fragment {
|
||||
@Override
|
||||
public void task(File file) {
|
||||
Log.d("Magisk", "Task firing");
|
||||
new Async.FlashZIP(getActivity(), repo.getId(), file.toString()).execute();
|
||||
new Async.FlashZIP(getActivity(), repo.getId(), file.toString()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
String filename = repo.getId().replace(" ", "") + ".zip";
|
||||
|
@ -112,7 +112,7 @@ public class RootFragment extends Fragment {
|
||||
}
|
||||
rootToggle.setEnabled(!autoRootStatus);
|
||||
autoRootToggle.setChecked(autoRootStatus);
|
||||
new updateUI().execute();
|
||||
new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
|
||||
rootToggle.setOnClickListener(toggle -> Utils.toggleRoot(((CompoundButton) toggle).isChecked(), getActivity()));
|
||||
|
||||
@ -131,7 +131,7 @@ public class RootFragment extends Fragment {
|
||||
|
||||
selinuxToggle.setOnClickListener(toggle -> {
|
||||
Shell.su(((CompoundButton) toggle).isChecked() ? "setenforce 1" : "setenforce 0");
|
||||
new updateUI().execute();
|
||||
new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
});
|
||||
|
||||
return view;
|
||||
|
@ -13,13 +13,17 @@ import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Shell;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class SplashActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
if (PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("theme","").equals("Dark")) {
|
||||
|
||||
SharedPreferences defaultPrefs = PreferenceManager.getDefaultSharedPreferences(getApplication());
|
||||
|
||||
if (defaultPrefs.getString("theme","").equals("Dark")) {
|
||||
setTheme(R.style.AppTheme_dh);
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -27,13 +31,12 @@ public class SplashActivity extends AppCompatActivity {
|
||||
//setups go here
|
||||
|
||||
// Set up default preferences,make sure we add "extra" blacklist entries.
|
||||
|
||||
PreferenceManager.setDefaultValues(this, R.xml.defaultpref, false);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplication());
|
||||
|
||||
if (!prefs.contains("auto_blacklist")) {
|
||||
|
||||
if (!defaultPrefs.contains("auto_blacklist")) {
|
||||
Logger.dh("AutoRootFragment: Setting default preferences for application");
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
SharedPreferences.Editor editor = defaultPrefs.edit();
|
||||
Set<String> set = new HashSet<>();
|
||||
set.add("com.google.android.apps.walletnfcrel");
|
||||
set.add("com.google.android.gms");
|
||||
@ -45,47 +48,27 @@ public class SplashActivity extends AppCompatActivity {
|
||||
// Set up toggle states based on preferences, start services, disable root if set
|
||||
if (Utils.autoToggleEnabled(getApplicationContext())) {
|
||||
if (!Utils.hasServicePermission(getApplicationContext())) {
|
||||
Utils.toggleAutoRoot(false,getApplicationContext());
|
||||
Utils.toggleAutoRoot(false, getApplicationContext());
|
||||
}
|
||||
}
|
||||
if (Utils.autoToggleEnabled(getApplicationContext())) {
|
||||
|
||||
if (!Utils.isMyServiceRunning(MonitorService.class, getApplicationContext())) {
|
||||
Intent myIntent = new Intent(getApplication(), MonitorService.class);
|
||||
getApplication().startService(myIntent);
|
||||
}
|
||||
} else {
|
||||
if (PreferenceManager.getDefaultSharedPreferences(getApplication()).getBoolean("keep_root_off", false)) {
|
||||
Utils.toggleRoot(false, getApplication());
|
||||
}
|
||||
} else if (defaultPrefs.getBoolean("keep_root_off", false)) {
|
||||
Utils.toggleRoot(false, getApplication());
|
||||
}
|
||||
|
||||
// Set up quick settings tile
|
||||
Utils.SetupQuickSettingsTile(getApplicationContext());
|
||||
if (defaultPrefs.getBoolean("enable_quicktile", false)) {
|
||||
Utils.SetupQuickSettingsTile(getApplicationContext());
|
||||
}
|
||||
|
||||
// Initialize
|
||||
|
||||
|
||||
if (Shell.rootAccess()) {
|
||||
if (!Utils.busyboxInstalled()) {
|
||||
String busybox = getApplicationContext().getApplicationInfo().nativeLibraryDir + "/libbusybox.so";
|
||||
Shell.su(
|
||||
"rm -rf /data/busybox",
|
||||
"mkdir -p /data/busybox",
|
||||
"cp -af " + busybox + " /data/busybox/busybox",
|
||||
"chmod 755 /data/busybox /data/busybox/busybox",
|
||||
"chcon u:object_r:system_file:s0 /data/busybox /data/busybox/busybox",
|
||||
"/data/busybox/busybox --install -s /data/busybox",
|
||||
"rm -f /data/busybox/su",
|
||||
"export PATH=/data/busybox:$PATH"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
new Async.CheckUpdates(this).execute();
|
||||
new Async.LoadModules(this).execute();
|
||||
new Async.LoadRepos(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
Utils.init(this);
|
||||
new Async.CheckUpdates(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
new Async.LoadModules(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
new Async.LoadRepos(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
new Async.BusyboxEnv(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
// Start main activity
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
|
@ -6,6 +6,7 @@ import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
public class Module extends BaseModule {
|
||||
@ -14,7 +15,7 @@ public class Module extends BaseModule {
|
||||
private String mDisableFile;
|
||||
|
||||
private String mZipUrl, mLogUrl;
|
||||
private boolean mEnable, mRemove, mUpdateAvailable = false, mIsInstalled;
|
||||
private boolean mEnable, mRemove, mUpdateAvailable = false;
|
||||
|
||||
public Module(Context context, String path) {
|
||||
|
||||
@ -38,75 +39,10 @@ public class Module extends BaseModule {
|
||||
if (mVersion == null)
|
||||
mVersion = context.getString(R.string.no_info_provided);
|
||||
|
||||
Log.d("Magisk","Module: Loaded module with ID of " + mId );
|
||||
Logger.dh("Module id: " + mId);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
if (this.mId != null && !this.mId.isEmpty()) {
|
||||
String preferenceString = "repo_" + this.mId;
|
||||
String preferenceKey = prefs.getString(preferenceString,"nope");
|
||||
Log.d("Magisk", "Module: Checking for preference named " + preferenceString);
|
||||
if (!preferenceKey.equals("nope")) {
|
||||
Log.d("Magisk", "Module: repo_" + mId + " found.");
|
||||
String entryString = prefs.getString("repo_" + mId, "");
|
||||
String[] subStrings = entryString.split("\n");
|
||||
for (String subKeys : subStrings) {
|
||||
String[] idEntry = subKeys.split("=", 2);
|
||||
if (idEntry[0].equals("id")) {
|
||||
if (idEntry.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (idEntry[1].equals(mId)) {
|
||||
Log.d("Magisk", "Module: Hey, I know " + mId + " is online...");
|
||||
mIsInstalled = true;
|
||||
} else mIsInstalled = false;
|
||||
}
|
||||
if (idEntry[0].equals("logUrl")) {
|
||||
mLogUrl = idEntry[1];
|
||||
}
|
||||
if (idEntry[0].equals("support")) {
|
||||
mSupportUrl = idEntry[1];
|
||||
}
|
||||
if (idEntry[0].equals("zipUrl")) {
|
||||
mZipUrl = idEntry[1];
|
||||
}
|
||||
if (idEntry[0].equals("donate")) {
|
||||
mDonateUrl = idEntry[1];
|
||||
}
|
||||
|
||||
if (idEntry[0].equals("versionCode")) {
|
||||
if (idEntry.length != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Integer.valueOf(idEntry[1]) > mVersionCode) {
|
||||
mUpdateAvailable = true;
|
||||
Log.d("Magisk", "Module: Hey, I have an update...");
|
||||
} else mUpdateAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
if (mIsInstalled) {
|
||||
editor.putBoolean("repo-isInstalled_" + mId, true);
|
||||
} else {
|
||||
editor.putBoolean("repo-isInstalled_" + mId, false);
|
||||
}
|
||||
|
||||
if (mUpdateAvailable) {
|
||||
editor.putBoolean("repo-canUpdate_" + mId, true);
|
||||
} else {
|
||||
editor.putBoolean("repo-canUpdate_" + mId, false);
|
||||
}
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
mEnable = !Utils.fileExist(mDisableFile);
|
||||
mRemove = Utils.fileExist(mRemoveFile);
|
||||
mEnable = !Utils.itemExist(mDisableFile);
|
||||
mRemove = Utils.itemExist(mRemoveFile);
|
||||
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,32 @@ import java.util.List;
|
||||
|
||||
public class Async {
|
||||
|
||||
public static class BusyboxEnv extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
Context mContext;
|
||||
|
||||
public BusyboxEnv(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
String toolPath = mContext.getApplicationInfo().dataDir + "/busybox";
|
||||
String busybox = mContext.getApplicationInfo().dataDir + "/lib/libbusybox.so";
|
||||
if (Shell.rootAccess() && !Utils.commandExists("unzip") && !Utils.itemExist(toolPath)) {
|
||||
Shell.su(true,
|
||||
"mkdir " + toolPath,
|
||||
"chmod 755 " + toolPath,
|
||||
"ln -s " + busybox + " " + toolPath + "/busybox",
|
||||
"for tool in $(" + toolPath + "/busybox --list); do",
|
||||
"ln -s " + busybox + " " + toolPath + "/$tool",
|
||||
"done"
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CheckUpdates extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private Context mContext;
|
||||
@ -100,7 +126,7 @@ public class Async {
|
||||
rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.phh)) {
|
||||
@Override
|
||||
public void task(File file) {
|
||||
new FlashZIP(mContext, mName, file.getPath()).execute();
|
||||
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
break;
|
||||
@ -110,7 +136,7 @@ public class Async {
|
||||
rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) {
|
||||
@Override
|
||||
public void task(File file) {
|
||||
new FlashZIP(mContext, mName, file.getPath()).execute();
|
||||
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
break;
|
||||
@ -127,7 +153,7 @@ public class Async {
|
||||
protected void done() {
|
||||
Utils.downloadAndReceive(temp, rootReceiver, link, filename);
|
||||
}
|
||||
}.execute();
|
||||
}.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
};
|
||||
Utils.downloadAndReceive(mContext, magiskReceiver, Utils.magiskLink, "latest_magisk.zip");
|
||||
@ -150,7 +176,7 @@ public class Async {
|
||||
new Utils.DownloadReceiver(mContext.getString(R.string.phh)) {
|
||||
@Override
|
||||
public void task(File file) {
|
||||
new FlashZIP(mContext, mName, file.getPath()).execute();
|
||||
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
},
|
||||
Utils.phhLink, "phhsu.zip");
|
||||
@ -161,7 +187,7 @@ public class Async {
|
||||
new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) {
|
||||
@Override
|
||||
public void task(File file) {
|
||||
new FlashZIP(mContext, mName, file.getPath()).execute();
|
||||
new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
|
||||
}
|
||||
},
|
||||
Utils.supersuLink, "supersu.zip");
|
||||
@ -186,17 +212,17 @@ public class Async {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
ModulesFragment.listModules.clear();
|
||||
Logger.dh("Loading modules");
|
||||
List<String> magisk = Utils.getModList(Utils.MAGISK_PATH);
|
||||
Log.d("Magisk", "Utils: Reload called, loading modules");
|
||||
List<String> magiskCache = Utils.getModList(Utils.MAGISK_CACHE_PATH);
|
||||
|
||||
for (String mod : magisk) {
|
||||
Log.d("Magisk", "Utils: Adding module from string " + mod);
|
||||
Logger.dh("Adding modules from " + mod);
|
||||
ModulesFragment.listModules.add(new Module(mContext, mod));
|
||||
}
|
||||
|
||||
for (String mod : magiskCache) {
|
||||
Log.d("Magisk", "Utils: Adding cache module from string " + mod);
|
||||
Logger.dh("Adding cache modules from " + mod);
|
||||
Module cacheMod = new Module(mContext, mod);
|
||||
// Prevent people forgot to change module.prop
|
||||
cacheMod.setCache();
|
||||
@ -205,6 +231,8 @@ public class Async {
|
||||
|
||||
Collections.sort(ModulesFragment.listModules, new Utils.ModuleComparator());
|
||||
|
||||
Logger.dh("Module load done");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -68,23 +68,6 @@ public class Shell {
|
||||
return rootStatus > 0;
|
||||
}
|
||||
|
||||
|
||||
public static boolean GetRootStatus() {
|
||||
if (Shell.sh("which su").contains("su")) {
|
||||
Shell.su(("setprop magisk.root 0"));
|
||||
}
|
||||
try {
|
||||
String rootStatus = Shell.su("getprop magisk.root").toString();
|
||||
return Integer.valueOf(rootStatus).equals(1);
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static List<String> sh(String... commands) {
|
||||
List<String> res = Collections.synchronizedList(new ArrayList<String>());
|
||||
|
||||
@ -126,46 +109,92 @@ public class Shell {
|
||||
return res;
|
||||
}
|
||||
|
||||
// Run with the same shell by default
|
||||
public static List<String> su(String... commands) {
|
||||
return su(false, commands);
|
||||
}
|
||||
|
||||
if(!Shell.rootAccess()) return null;
|
||||
public static List<String> su(boolean newShell, String... commands) {
|
||||
List<String> res;
|
||||
Process process;
|
||||
DataOutputStream STDIN;
|
||||
StreamGobbler STDOUT;
|
||||
|
||||
rootOutList.clear();
|
||||
if (newShell) {
|
||||
res = Collections.synchronizedList(new ArrayList<String>());
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(sh("getprop magisk.supath").get(0) + "/su");
|
||||
STDIN = new DataOutputStream(process.getOutputStream());
|
||||
STDOUT = new StreamGobbler(process.getInputStream(), res);
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
// Improper root
|
||||
process = Runtime.getRuntime().exec("su");
|
||||
STDIN = new DataOutputStream(process.getOutputStream());
|
||||
STDOUT = new StreamGobbler(process.getInputStream(), res);
|
||||
} catch (IOException err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
STDOUT.start();
|
||||
} else {
|
||||
process = rootShell;
|
||||
STDIN = rootSTDIN;
|
||||
STDOUT = rootSTDOUT;
|
||||
res = rootOutList;
|
||||
res.clear();
|
||||
}
|
||||
|
||||
try {
|
||||
for (String write : commands) {
|
||||
rootSTDIN.write((write + "\n").getBytes("UTF-8"));
|
||||
rootSTDIN.flush();
|
||||
STDIN.write((write + "\n").getBytes("UTF-8"));
|
||||
STDIN.flush();
|
||||
}
|
||||
if (newShell) {
|
||||
STDIN.write("exit\n".getBytes("UTF-8"));
|
||||
STDIN.flush();
|
||||
process.waitFor();
|
||||
|
||||
try {
|
||||
STDIN.close();
|
||||
} catch (IOException ignore) {
|
||||
// might be closed already
|
||||
}
|
||||
|
||||
STDOUT.join();
|
||||
process.destroy();
|
||||
} else {
|
||||
STDIN.write(("echo \' \'\n").getBytes("UTF-8"));
|
||||
STDIN.flush();
|
||||
STDIN.write(("echo \'-done-\'\n").getBytes("UTF-8"));
|
||||
STDIN.flush();
|
||||
while (true) {
|
||||
try {
|
||||
// Process terminated, it means the interactive shell has some issues
|
||||
process.exitValue();
|
||||
return null;
|
||||
} catch (IllegalThreadStateException e) {
|
||||
// Process still running, gobble output until done
|
||||
int end = res.size() - 1;
|
||||
if (end > 0) {
|
||||
if (res.get(end).equals("-done-")) {
|
||||
res.remove(end);
|
||||
res.remove(end - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try { STDOUT.join(100); } catch (InterruptedException err) { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
rootSTDIN.write(("echo \' \'\n").getBytes("UTF-8"));
|
||||
rootSTDIN.flush();
|
||||
rootSTDIN.write(("echo \'-done-\'\n").getBytes("UTF-8"));
|
||||
rootSTDIN.flush();
|
||||
} catch (IOException e) {
|
||||
if (!e.getMessage().contains("EPIPE")) {
|
||||
return null;
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// Process terminated, it means the interactive shell cannot be initialized
|
||||
rootShell.exitValue();
|
||||
return null;
|
||||
} catch (IllegalThreadStateException e) {
|
||||
// Process still running, gobble output until done
|
||||
int end = rootOutList.size() - 1;
|
||||
if (rootOutList != null && end > 0) {
|
||||
if (rootOutList.get(end).equals("-done-")) {
|
||||
rootOutList.remove(end);
|
||||
rootOutList.remove(end - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try { rootSTDOUT.join(100); } catch (InterruptedException err) { return null; }
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(rootOutList);
|
||||
return new ArrayList<>(res);
|
||||
}
|
||||
}
|
||||
|
@ -69,20 +69,13 @@ public class Utils {
|
||||
} else {
|
||||
magiskVersion = Integer.parseInt(ret.get(0));
|
||||
}
|
||||
if (!Shell.rootAccess()) {
|
||||
Snackbar.make(((Activity) context).findViewById(android.R.id.content), R.string.no_root_access, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("keep_root_off", false)) {
|
||||
Utils.toggleRoot(false, context);
|
||||
}
|
||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enable_quicktile", false)) {
|
||||
Utils.SetupQuickSettingsTile(context);
|
||||
}
|
||||
String toolPath = context.getApplicationInfo().dataDir + "/busybox";
|
||||
Shell.su("PATH=$PATH:" + toolPath);
|
||||
}
|
||||
|
||||
public static boolean fileExist(String path) {
|
||||
public static boolean itemExist(String path) {
|
||||
List<String> ret;
|
||||
String command = "if [ -f " + path + " ]; then echo true; else echo false; fi";
|
||||
String command = "if [ -e " + path + " ]; then echo true; else echo false; fi";
|
||||
if (Shell.rootAccess()) {
|
||||
ret = Shell.su(command);
|
||||
} else {
|
||||
@ -91,22 +84,15 @@ public class Utils {
|
||||
return Boolean.parseBoolean(ret.get(0));
|
||||
}
|
||||
|
||||
public static boolean busyboxInstalled() {
|
||||
public static boolean commandExists(String s) {
|
||||
List<String> ret;
|
||||
String command = "if [ -d /data/busybox ]; then echo true; else echo false; fi";
|
||||
if (Shell.rootAccess()) {
|
||||
ret = Shell.su(command);
|
||||
} else {
|
||||
ret = Shell.sh(command);
|
||||
}
|
||||
String command = "if [ -z $(which " + s + ") ]; then echo false; else echo true; fi";
|
||||
ret = Shell.sh(command);
|
||||
return Boolean.parseBoolean(ret.get(0));
|
||||
}
|
||||
|
||||
public static boolean rootEnabled() {
|
||||
List<String> ret;
|
||||
String command = "if [ -z $(which su) ]; then echo false; else echo true; fi";
|
||||
ret = Shell.sh(command);
|
||||
return Boolean.parseBoolean(ret.get(0));
|
||||
return commandExists("su");
|
||||
}
|
||||
|
||||
public static boolean autoToggleEnabled(Context context) {
|
||||
|
@ -33,14 +33,12 @@ public class WebRequest {
|
||||
* @requestmethod - http request method
|
||||
*/
|
||||
public static String makeWebServiceCall(String url, int requestmethod) {
|
||||
Log.d("Magisk","WebRequest: Service call received for URL " + url);
|
||||
return makeWebServiceCall(url, requestmethod, null, false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) {
|
||||
Log.d("Magisk","WebRequest: Service call(bool) received for URL " + url);
|
||||
return makeWebServiceCall(url, requestmethod, null, addNewLines);
|
||||
|
||||
}
|
||||
@ -54,6 +52,7 @@ public class WebRequest {
|
||||
*/
|
||||
public static String makeWebServiceCall(String urladdress, int requestmethod,
|
||||
HashMap<String, String> params, boolean addNewLines) {
|
||||
Logger.dh("WebRequest: Service call " + urladdress);
|
||||
URL url;
|
||||
String response = "";
|
||||
try {
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,5 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<Preference
|
||||
android:key="theme"
|
||||
android:defaultValue="Default"
|
||||
/>
|
||||
<Preference
|
||||
android:key="auto_blacklist"
|
||||
android:defaultValue="com.google.android.apps.walletnfcrel"
|
||||
|
Loading…
x
Reference in New Issue
Block a user