diff --git a/app/src/main/java/com/topjohnwu/magisk/LogFragment.java b/app/src/main/java/com/topjohnwu/magisk/LogFragment.java index eddc02c45..d39f371d7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/LogFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/LogFragment.java @@ -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(); } diff --git a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java index 16e8da0d5..7079479e5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/MagiskFragment.java @@ -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")) diff --git a/app/src/main/java/com/topjohnwu/magisk/MainActivity.java b/app/src/main/java/com/topjohnwu/magisk/MainActivity.java index 194d51471..de998eaf8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/MainActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/MainActivity.java @@ -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); diff --git a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java index fe7ba2676..e6f63a930 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/ModulesAdapter.java @@ -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 { 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) { diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java index f3b35de70..01720b46e 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java +++ b/app/src/main/java/com/topjohnwu/magisk/ReposAdapter.java @@ -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 @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"; diff --git a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java index 374963da8..2bc59bc01 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/ReposFragment.java @@ -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"; diff --git a/app/src/main/java/com/topjohnwu/magisk/RootFragment.java b/app/src/main/java/com/topjohnwu/magisk/RootFragment.java index 578f99728..6be2ce78c 100644 --- a/app/src/main/java/com/topjohnwu/magisk/RootFragment.java +++ b/app/src/main/java/com/topjohnwu/magisk/RootFragment.java @@ -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; diff --git a/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java b/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java index eff4d3562..888affe51 100644 --- a/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java +++ b/app/src/main/java/com/topjohnwu/magisk/SplashActivity.java @@ -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 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); diff --git a/app/src/main/java/com/topjohnwu/magisk/module/Module.java b/app/src/main/java/com/topjohnwu/magisk/module/Module.java index 006d652e3..16fb6e270 100644 --- a/app/src/main/java/com/topjohnwu/magisk/module/Module.java +++ b/app/src/main/java/com/topjohnwu/magisk/module/Module.java @@ -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); } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Async.java b/app/src/main/java/com/topjohnwu/magisk/utils/Async.java index d978f41dc..bdccb26c9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Async.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Async.java @@ -35,6 +35,32 @@ import java.util.List; public class Async { + public static class BusyboxEnv extends AsyncTask { + + 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 { 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 magisk = Utils.getModList(Utils.MAGISK_PATH); - Log.d("Magisk", "Utils: Reload called, loading modules"); List 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; } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java b/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java index 8da968dfa..1464812c6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Shell.java @@ -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 sh(String... commands) { List res = Collections.synchronizedList(new ArrayList()); @@ -126,46 +109,92 @@ public class Shell { return res; } + // Run with the same shell by default public static List su(String... commands) { + return su(false, commands); + } - if(!Shell.rootAccess()) return null; + public static List su(boolean newShell, String... commands) { + List res; + Process process; + DataOutputStream STDIN; + StreamGobbler STDOUT; - rootOutList.clear(); + if (newShell) { + res = Collections.synchronizedList(new ArrayList()); + 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); } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java index fcb67ab9d..132e0a8d8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/Utils.java @@ -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 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 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 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) { diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java index 1e6d2a535..98898304b 100644 --- a/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java +++ b/app/src/main/java/com/topjohnwu/magisk/utils/WebRequest.java @@ -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 params, boolean addNewLines) { + Logger.dh("WebRequest: Service call " + urladdress); URL url; String response = ""; try { diff --git a/app/src/main/jniLibs/armeabi/libbusybox.so b/app/src/main/jniLibs/armeabi/libbusybox.so index 67bfb88e1..985254672 100644 Binary files a/app/src/main/jniLibs/armeabi/libbusybox.so and b/app/src/main/jniLibs/armeabi/libbusybox.so differ diff --git a/app/src/main/jniLibs/x86/libbusybox.so b/app/src/main/jniLibs/x86/libbusybox.so index a7462efe8..a83050ad9 100644 Binary files a/app/src/main/jniLibs/x86/libbusybox.so and b/app/src/main/jniLibs/x86/libbusybox.so differ diff --git a/app/src/main/res/xml/defaultpref.xml b/app/src/main/res/xml/defaultpref.xml index f5ae9026e..3094a2b2e 100644 --- a/app/src/main/res/xml/defaultpref.xml +++ b/app/src/main/res/xml/defaultpref.xml @@ -1,5 +1,9 @@ +