Update busybox; Improve environment setup

This commit is contained in:
topjohnwu 2016-09-25 21:31:38 +08:00
parent dac85757b3
commit 89932b325d
17 changed files with 169 additions and 204 deletions

View File

@ -104,13 +104,13 @@ public class LogFragment extends Fragment {
} }
private void reloadErrorLog() { private void reloadErrorLog() {
new LogsManager(true).execute(); new LogsManager(true).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
svLog.post(() -> svLog.scrollTo(0, txtLog.getHeight())); svLog.post(() -> svLog.scrollTo(0, txtLog.getHeight()));
hsvLog.post(() -> hsvLog.scrollTo(0, 0)); hsvLog.post(() -> hsvLog.scrollTo(0, 0));
} }
private void clear() { private void clear() {
new LogsManager(false).execute(); new LogsManager(false).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
reloadErrorLog(); reloadErrorLog();
} }

View File

@ -70,7 +70,7 @@ public class MagiskFragment extends Fragment {
ta0.recycle(); ta0.recycle();
ta1.recycle(); ta1.recycle();
ta2.recycle(); ta2.recycle();
new updateUI().execute(); new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
return v; return v;
} }
@ -132,7 +132,7 @@ public class MagiskFragment extends Fragment {
new Utils.DownloadReceiver(getString(R.string.magisk)) { new Utils.DownloadReceiver(getString(R.string.magisk)) {
@Override @Override
public void task(File file) { 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")) Utils.magiskLink, "latest_magisk.zip"))

View File

@ -12,6 +12,7 @@ import android.preference.PreferenceManager;
import android.support.annotation.IdRes; import android.support.annotation.IdRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView; import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.view.GravityCompat; import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
@ -22,6 +23,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import com.topjohnwu.magisk.utils.Logger; import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import butterknife.BindView; import butterknife.BindView;
@ -56,13 +58,15 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
ButterKnife.bind(this); ButterKnife.bind(this);
// Startups
Utils.init(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); 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( this.getFragmentManager().addOnBackStackChangedListener(
() -> { () -> {
Fragment hm = getFragmentManager().findFragmentByTag("root"); Fragment hm = getFragmentManager().findFragmentByTag("root");
@ -108,7 +112,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} }
} }
} }
); );
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
@ -149,12 +152,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
} }
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override @Override
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);

View File

@ -5,6 +5,7 @@ import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
@ -110,7 +111,7 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
@Override @Override
public void task(File file) { public void task(File file) {
Log.d("Magisk", "Task firing"); 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"; String filename = mModule.getId().replace(" ", "") + ".zip";

View File

@ -62,8 +62,8 @@ public class ModulesFragment extends Fragment {
mSwipeRefreshLayout.setOnRefreshListener(() -> { mSwipeRefreshLayout.setOnRefreshListener(() -> {
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
new Async.LoadModules(getActivity()).execute(); new Async.LoadModules(getActivity()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
new updateUI().execute(); new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
prefs.edit().putBoolean("ignoreUpdateAlerts", false).apply(); 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; return viewMain;
} }
@ -88,7 +88,7 @@ public class ModulesFragment extends Fragment {
final Uri uri = data.getData(); final Uri uri = data.getData();
try { try {
// Get the file path from the URI // 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); FileInfo fileInfo = FileUtils.getFileInfo(getActivity(), uri);
} catch (Exception e) { } catch (Exception e) {

View File

@ -6,6 +6,7 @@ import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Color; import android.graphics.Color;
import android.os.AsyncTask;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
@ -148,7 +149,7 @@ public class ReposAdapter extends RecyclerView.Adapter<ReposAdapter.ViewHolder>
@Override @Override
public void task(File file) { public void task(File file) {
Log.d("Magisk", "Task firing"); 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"; String filename = repo.getId().replace(" ", "") + ".zip";

View File

@ -2,6 +2,7 @@ package com.topjohnwu.magisk;
import android.app.Fragment; import android.app.Fragment;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout;
@ -126,7 +127,7 @@ public class ReposFragment extends Fragment {
@Override @Override
public void task(File file) { public void task(File file) {
Log.d("Magisk", "Task firing"); 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"; String filename = repo.getId().replace(" ", "") + ".zip";

View File

@ -112,7 +112,7 @@ public class RootFragment extends Fragment {
} }
rootToggle.setEnabled(!autoRootStatus); rootToggle.setEnabled(!autoRootStatus);
autoRootToggle.setChecked(autoRootStatus); autoRootToggle.setChecked(autoRootStatus);
new updateUI().execute(); new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
rootToggle.setOnClickListener(toggle -> Utils.toggleRoot(((CompoundButton) toggle).isChecked(), getActivity())); rootToggle.setOnClickListener(toggle -> Utils.toggleRoot(((CompoundButton) toggle).isChecked(), getActivity()));
@ -131,7 +131,7 @@ public class RootFragment extends Fragment {
selinuxToggle.setOnClickListener(toggle -> { selinuxToggle.setOnClickListener(toggle -> {
Shell.su(((CompoundButton) toggle).isChecked() ? "setenforce 1" : "setenforce 0"); Shell.su(((CompoundButton) toggle).isChecked() ? "setenforce 1" : "setenforce 0");
new updateUI().execute(); new updateUI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}); });
return view; return view;

View File

@ -13,13 +13,17 @@ import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Shell; import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import java.io.File;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
public class SplashActivity extends AppCompatActivity { public class SplashActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { 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); setTheme(R.style.AppTheme_dh);
} }
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -27,13 +31,12 @@ public class SplashActivity extends AppCompatActivity {
//setups go here //setups go here
// Set up default preferences,make sure we add "extra" blacklist entries. // Set up default preferences,make sure we add "extra" blacklist entries.
PreferenceManager.setDefaultValues(this, R.xml.defaultpref, false); 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"); Logger.dh("AutoRootFragment: Setting default preferences for application");
SharedPreferences.Editor editor = prefs.edit(); SharedPreferences.Editor editor = defaultPrefs.edit();
Set<String> set = new HashSet<>(); Set<String> set = new HashSet<>();
set.add("com.google.android.apps.walletnfcrel"); set.add("com.google.android.apps.walletnfcrel");
set.add("com.google.android.gms"); 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 // Set up toggle states based on preferences, start services, disable root if set
if (Utils.autoToggleEnabled(getApplicationContext())) { if (Utils.autoToggleEnabled(getApplicationContext())) {
if (!Utils.hasServicePermission(getApplicationContext())) { if (!Utils.hasServicePermission(getApplicationContext())) {
Utils.toggleAutoRoot(false,getApplicationContext()); Utils.toggleAutoRoot(false, getApplicationContext());
} }
}
if (Utils.autoToggleEnabled(getApplicationContext())) {
if (!Utils.isMyServiceRunning(MonitorService.class, getApplicationContext())) { if (!Utils.isMyServiceRunning(MonitorService.class, getApplicationContext())) {
Intent myIntent = new Intent(getApplication(), MonitorService.class); Intent myIntent = new Intent(getApplication(), MonitorService.class);
getApplication().startService(myIntent); getApplication().startService(myIntent);
} }
} else { } else if (defaultPrefs.getBoolean("keep_root_off", false)) {
if (PreferenceManager.getDefaultSharedPreferences(getApplication()).getBoolean("keep_root_off", false)) { Utils.toggleRoot(false, getApplication());
Utils.toggleRoot(false, getApplication());
}
} }
// Set up quick settings tile // Set up quick settings tile
Utils.SetupQuickSettingsTile(getApplicationContext()); if (defaultPrefs.getBoolean("enable_quicktile", false)) {
Utils.SetupQuickSettingsTile(getApplicationContext());
}
// Initialize // Initialize
Utils.init(this);
new Async.CheckUpdates(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
if (Shell.rootAccess()) { new Async.LoadModules(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
if (!Utils.busyboxInstalled()) { new Async.LoadRepos(this).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
String busybox = getApplicationContext().getApplicationInfo().nativeLibraryDir + "/libbusybox.so"; new Async.BusyboxEnv(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
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);
// Start main activity // Start main activity
Intent intent = new Intent(this, MainActivity.class); Intent intent = new Intent(this, MainActivity.class);

View File

@ -6,6 +6,7 @@ import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
public class Module extends BaseModule { public class Module extends BaseModule {
@ -14,7 +15,7 @@ public class Module extends BaseModule {
private String mDisableFile; private String mDisableFile;
private String mZipUrl, mLogUrl; private String mZipUrl, mLogUrl;
private boolean mEnable, mRemove, mUpdateAvailable = false, mIsInstalled; private boolean mEnable, mRemove, mUpdateAvailable = false;
public Module(Context context, String path) { public Module(Context context, String path) {
@ -38,75 +39,10 @@ public class Module extends BaseModule {
if (mVersion == null) if (mVersion == null)
mVersion = context.getString(R.string.no_info_provided); 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); mEnable = !Utils.itemExist(mDisableFile);
mRemove = Utils.itemExist(mRemoveFile);
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);
} }

View File

@ -35,6 +35,32 @@ import java.util.List;
public class Async { 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> { public static class CheckUpdates extends AsyncTask<Void, Void, Void> {
private Context mContext; private Context mContext;
@ -100,7 +126,7 @@ public class Async {
rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.phh)) { rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.phh)) {
@Override @Override
public void task(File file) { public void task(File file) {
new FlashZIP(mContext, mName, file.getPath()).execute(); new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
} }
}; };
break; break;
@ -110,7 +136,7 @@ public class Async {
rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) { rootReceiver = new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) {
@Override @Override
public void task(File file) { public void task(File file) {
new FlashZIP(mContext, mName, file.getPath()).execute(); new FlashZIP(mContext, mName, file.getPath()).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
} }
}; };
break; break;
@ -127,7 +153,7 @@ public class Async {
protected void done() { protected void done() {
Utils.downloadAndReceive(temp, rootReceiver, link, filename); Utils.downloadAndReceive(temp, rootReceiver, link, filename);
} }
}.execute(); }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
} }
}; };
Utils.downloadAndReceive(mContext, magiskReceiver, Utils.magiskLink, "latest_magisk.zip"); Utils.downloadAndReceive(mContext, magiskReceiver, Utils.magiskLink, "latest_magisk.zip");
@ -150,7 +176,7 @@ public class Async {
new Utils.DownloadReceiver(mContext.getString(R.string.phh)) { new Utils.DownloadReceiver(mContext.getString(R.string.phh)) {
@Override @Override
public void task(File file) { 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"); Utils.phhLink, "phhsu.zip");
@ -161,7 +187,7 @@ public class Async {
new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) { new Utils.DownloadReceiver(mContext.getString(R.string.supersu)) {
@Override @Override
public void task(File file) { 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"); Utils.supersuLink, "supersu.zip");
@ -186,17 +212,17 @@ public class Async {
@Override @Override
protected Void doInBackground(Void... voids) { protected Void doInBackground(Void... voids) {
ModulesFragment.listModules.clear(); ModulesFragment.listModules.clear();
Logger.dh("Loading modules");
List<String> magisk = Utils.getModList(Utils.MAGISK_PATH); 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); List<String> magiskCache = Utils.getModList(Utils.MAGISK_CACHE_PATH);
for (String mod : magisk) { 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)); ModulesFragment.listModules.add(new Module(mContext, mod));
} }
for (String mod : magiskCache) { 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); Module cacheMod = new Module(mContext, mod);
// Prevent people forgot to change module.prop // Prevent people forgot to change module.prop
cacheMod.setCache(); cacheMod.setCache();
@ -205,6 +231,8 @@ public class Async {
Collections.sort(ModulesFragment.listModules, new Utils.ModuleComparator()); Collections.sort(ModulesFragment.listModules, new Utils.ModuleComparator());
Logger.dh("Module load done");
return null; return null;
} }

View File

@ -68,23 +68,6 @@ public class Shell {
return rootStatus > 0; 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) { public static List<String> sh(String... commands) {
List<String> res = Collections.synchronizedList(new ArrayList<String>()); List<String> res = Collections.synchronizedList(new ArrayList<String>());
@ -126,46 +109,92 @@ public class Shell {
return res; return res;
} }
// Run with the same shell by default
public static List<String> su(String... commands) { 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 { try {
for (String write : commands) { for (String write : commands) {
rootSTDIN.write((write + "\n").getBytes("UTF-8")); STDIN.write((write + "\n").getBytes("UTF-8"));
rootSTDIN.flush(); 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) { } catch (IOException e) {
if (!e.getMessage().contains("EPIPE")) { if (!e.getMessage().contains("EPIPE")) {
return null; return null;
} }
} catch(InterruptedException e) {
return null;
} }
while (true) { return new ArrayList<>(res);
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);
} }
} }

View File

@ -69,20 +69,13 @@ public class Utils {
} else { } else {
magiskVersion = Integer.parseInt(ret.get(0)); magiskVersion = Integer.parseInt(ret.get(0));
} }
if (!Shell.rootAccess()) { String toolPath = context.getApplicationInfo().dataDir + "/busybox";
Snackbar.make(((Activity) context).findViewById(android.R.id.content), R.string.no_root_access, Snackbar.LENGTH_LONG).show(); Shell.su("PATH=$PATH:" + toolPath);
}
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("keep_root_off", false)) {
Utils.toggleRoot(false, context);
}
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enable_quicktile", false)) {
Utils.SetupQuickSettingsTile(context);
}
} }
public static boolean fileExist(String path) { public static boolean itemExist(String path) {
List<String> ret; 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()) { if (Shell.rootAccess()) {
ret = Shell.su(command); ret = Shell.su(command);
} else { } else {
@ -91,22 +84,15 @@ public class Utils {
return Boolean.parseBoolean(ret.get(0)); return Boolean.parseBoolean(ret.get(0));
} }
public static boolean busyboxInstalled() { public static boolean commandExists(String s) {
List<String> ret; List<String> ret;
String command = "if [ -d /data/busybox ]; then echo true; else echo false; fi"; String command = "if [ -z $(which " + s + ") ]; then echo false; else echo true; fi";
if (Shell.rootAccess()) { ret = Shell.sh(command);
ret = Shell.su(command);
} else {
ret = Shell.sh(command);
}
return Boolean.parseBoolean(ret.get(0)); return Boolean.parseBoolean(ret.get(0));
} }
public static boolean rootEnabled() { public static boolean rootEnabled() {
List<String> ret; return commandExists("su");
String command = "if [ -z $(which su) ]; then echo false; else echo true; fi";
ret = Shell.sh(command);
return Boolean.parseBoolean(ret.get(0));
} }
public static boolean autoToggleEnabled(Context context) { public static boolean autoToggleEnabled(Context context) {

View File

@ -33,14 +33,12 @@ public class WebRequest {
* @requestmethod - http request method * @requestmethod - http request method
*/ */
public static String makeWebServiceCall(String url, int requestmethod) { public static String makeWebServiceCall(String url, int requestmethod) {
Log.d("Magisk","WebRequest: Service call received for URL " + url);
return makeWebServiceCall(url, requestmethod, null, false); return makeWebServiceCall(url, requestmethod, null, false);
} }
public static String makeWebServiceCall(String url, int requestmethod, boolean addNewLines) { 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); return makeWebServiceCall(url, requestmethod, null, addNewLines);
} }
@ -54,6 +52,7 @@ public class WebRequest {
*/ */
public static String makeWebServiceCall(String urladdress, int requestmethod, public static String makeWebServiceCall(String urladdress, int requestmethod,
HashMap<String, String> params, boolean addNewLines) { HashMap<String, String> params, boolean addNewLines) {
Logger.dh("WebRequest: Service call " + urladdress);
URL url; URL url;
String response = ""; String response = "";
try { try {

View File

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:key="theme"
android:defaultValue="Default"
/>
<Preference <Preference
android:key="auto_blacklist" android:key="auto_blacklist"
android:defaultValue="com.google.android.apps.walletnfcrel" android:defaultValue="com.google.android.apps.walletnfcrel"