Use Java synchronize instead serial tasks

This commit is contained in:
topjohnwu 2017-06-06 03:06:23 +08:00
parent ff6938280e
commit efeddda328
17 changed files with 143 additions and 146 deletions

View File

@ -24,7 +24,7 @@ import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.SerialTask;
import com.topjohnwu.magisk.asyncs.RootTask;
import com.topjohnwu.magisk.components.Fragment;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Shell;
@ -127,14 +127,14 @@ public class MagiskLogFragment extends Fragment {
}
}
public class LogManager extends SerialTask<Object, Void, Object> {
private class LogManager extends RootTask<Object, Void, Object> {
int mode;
File targetFile;
@SuppressLint("DefaultLocale")
@Override
protected Object doInBackground(Object... params) {
protected Object doInRoot(Object... params) {
mode = (int) params[0];
switch (mode) {
case 0:

View File

@ -12,7 +12,6 @@ import android.support.v7.widget.Toolbar;
import android.widget.Toast;
import com.topjohnwu.magisk.asyncs.MagiskHide;
import com.topjohnwu.magisk.asyncs.SerialTask;
import com.topjohnwu.magisk.components.Activity;
import com.topjohnwu.magisk.components.AlertDialogBuilder;
import com.topjohnwu.magisk.database.SuDatabaseHelper;
@ -140,18 +139,11 @@ public class SettingsActivity extends Activity {
break;
case "disable":
enabled = prefs.getBoolean("disable", false);
new SerialTask<Void, Void, Void>() {
private boolean enable = enabled;
@Override
protected Void doInBackground(Void... voids) {
if (enable) {
Utils.createFile(MagiskManager.MAGISK_DISABLE_FILE);
} else {
Utils.removeItem(MagiskManager.MAGISK_DISABLE_FILE);
}
return null;
}
}.exec();
if (enabled) {
Utils.createFile(MagiskManager.MAGISK_DISABLE_FILE);
} else {
Utils.removeItem(MagiskManager.MAGISK_DISABLE_FILE);
}
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
break;
case "magiskhide":
@ -173,20 +165,15 @@ public class SettingsActivity extends Activity {
break;
case "hosts":
enabled = prefs.getBoolean("hosts", false);
new SerialTask<Void, Void, Void>() {
private boolean enable = enabled;
@Override
protected Void doInBackground(Void... voids) {
if (enable) {
Shell.su("cp -af /system/etc/hosts /magisk/.core/hosts",
"mount -o bind /magisk/.core/hosts /system/etc/hosts");
} else {
Shell.su("umount -l /system/etc/hosts",
"rm -f /magisk/.core/hosts");
}
return null;
}
}.exec();
if (enabled) {
Shell.su_async(null,
"cp -af /system/etc/hosts /magisk/.core/hosts",
"mount -o bind /magisk/.core/hosts /system/etc/hosts");
} else {
Shell.su_async(null,
"umount -l /system/etc/hosts",
"rm -f /magisk/.core/hosts");
}
break;
case "su_access":
magiskManager.suAccessState = Utils.getPrefsInt(prefs, "su_access", 3);

View File

@ -25,28 +25,18 @@ public class SplashActivity extends Activity{
super.onCreate(savedInstanceState);
MagiskManager magiskManager = getApplicationContext();
// Init the info and configs and root shell
magiskManager.init();
getApplicationContext().init();
// Now fire all async tasks
new GetBootBlocks(this).exec();
new LoadModules(this) {
@Override
protected void onPostExecute(Void v) {
super.onPostExecute(v);
if (Utils.checkNetworkStatus(activity)) {
new LoadRepos(activity).exec();
}
}
}.exec();
new LoadModules(this).setCallBack(() -> new LoadRepos(this).exec()).exec();
new LoadApps(this).exec();
if (Utils.checkNetworkStatus(this)) {
// Initialize the update check service, notify every 12 hours
if (!TextUtils.equals("install", getIntent().getStringExtra(MagiskManager.INTENT_SECTION))) {
ComponentName service = new ComponentName(magiskManager, UpdateCheckService.class);
ComponentName service = new ComponentName(this, UpdateCheckService.class);
JobInfo jobInfo = new JobInfo.Builder(UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
@ -57,7 +47,7 @@ public class SplashActivity extends Activity{
}
}
Intent intent = new Intent(magiskManager, MainActivity.class);
Intent intent = new Intent(this, MainActivity.class);
String section = getIntent().getStringExtra(MagiskManager.INTENT_SECTION);
if (section != null) {
intent.putExtra(MagiskManager.INTENT_SECTION, section);

View File

@ -12,7 +12,6 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.SerialTask;
import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.module.Module;
import com.topjohnwu.magisk.utils.Shell;
@ -53,44 +52,31 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setChecked(module.isEnabled());
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> new SerialTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
if (isChecked) {
module.removeDisableFile();
} else {
module.createDisableFile();
}
return null;
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
int snack;
if (isChecked) {
module.removeDisableFile();
snack = R.string.disable_file_removed;
} else {
module.createDisableFile();
snack = R.string.disable_file_created;
}
SnackbarMaker.make(holder.itemView, snack, Snackbar.LENGTH_SHORT).show();
});
@Override
protected void onPostExecute(Void v) {
int snack = isChecked ? R.string.disable_file_removed : R.string.disable_file_created;
SnackbarMaker.make(holder.itemView, snack, Snackbar.LENGTH_SHORT).show();
holder.delete.setOnClickListener(v -> {
boolean removed = module.willBeRemoved();
int snack;
if (removed) {
module.deleteRemoveFile();
snack = R.string.remove_file_deleted;
} else {
module.createRemoveFile();
snack = R.string.remove_file_created;
}
}.exec());
holder.delete.setOnClickListener(v -> new SerialTask<Void, Void, Void>() {
private final boolean removed = module.willBeRemoved();
@Override
protected Void doInBackground(Void... voids) {
if (removed) {
module.deleteRemoveFile();
} else {
module.createRemoveFile();
}
return null;
}
@Override
protected void onPostExecute(Void v) {
int snack = removed ? R.string.remove_file_deleted : R.string.remove_file_created;
SnackbarMaker.make(holder.itemView, snack, Snackbar.LENGTH_SHORT).show();
updateDeleteButton(holder, module);
}
}.exec());
SnackbarMaker.make(holder.itemView, snack, Snackbar.LENGTH_SHORT).show();
updateDeleteButton(holder, module);
});
if (module.isUpdated()) {
holder.notice.setVisibility(View.VISIBLE);

View File

@ -68,5 +68,6 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
magiskManager.updateCheckDone.trigger();
super.onPostExecute(v);
}
}

View File

@ -21,7 +21,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
public class FlashZip extends SerialTask<Void, String, Integer> {
public class FlashZip extends RootTask<Void, String, Integer> {
private Uri mUri;
private File mCachedFile, mScriptFile, mCheckFile;
@ -96,7 +96,7 @@ public class FlashZip extends SerialTask<Void, String, Integer> {
}
@Override
protected Integer doInBackground(Void... voids) {
protected Integer doInRoot(Void... voids) {
Logger.dev("FlashZip Running... " + mFilename);
List<String> ret;
try {
@ -124,7 +124,6 @@ public class FlashZip extends SerialTask<Void, String, Integer> {
// -1 = error, manual install; 0 = invalid zip; 1 = success
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
progress.dismiss();
switch (result) {
case -1:
@ -138,6 +137,7 @@ public class FlashZip extends SerialTask<Void, String, Integer> {
onSuccess();
break;
}
super.onPostExecute(result);
}
protected void onSuccess() {

View File

@ -5,15 +5,17 @@ import android.app.Activity;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
public class GetBootBlocks extends SerialTask<Void, Void, Void> {
public class GetBootBlocks extends RootTask<Void, Void, Void> {
public GetBootBlocks(Activity context) {
super(context);
}
@Override
protected Void doInBackground(Void... params) {
magiskManager.blockList = Shell.su("ls /dev/block | grep mmc");
protected Void doInRoot(Void... params) {
magiskManager.blockList = Shell.su(
"find /dev/block -type b -maxdepth 1 | grep -v -E \"loop|ram|dm-0\""
);
if (magiskManager.bootBlock == null) {
magiskManager.bootBlock = Utils.detectBootImage();
}
@ -23,5 +25,6 @@ public class GetBootBlocks extends SerialTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void v) {
magiskManager.blockDetectionDone.trigger();
super.onPostExecute(v);
}
}

View File

@ -9,14 +9,14 @@ import com.topjohnwu.magisk.utils.Logger;
import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.magisk.utils.ValueSortedMap;
public class LoadModules extends SerialTask<Void, Void, Void> {
public class LoadModules extends RootTask<Void, Void, Void> {
public LoadModules(Activity context) {
super(context);
}
@Override
protected Void doInBackground(Void... voids) {
protected Void doInRoot(Void... voids) {
Logger.dev("LoadModules: Loading modules");
magiskManager.moduleMap = new ValueSortedMap<>();
@ -37,5 +37,6 @@ public class LoadModules extends SerialTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void v) {
magiskManager.moduleLoadDone.trigger();
super.onPostExecute(v);
}
}

View File

@ -184,5 +184,6 @@ public class LoadRepos extends ParallelTask<Void, Void, Void> {
@Override
protected void onPostExecute(Void v) {
magiskManager.repoLoadDone.trigger();
super.onPostExecute(v);
}
}

View File

@ -6,7 +6,7 @@ import com.topjohnwu.magisk.utils.Shell;
import java.util.List;
public class MagiskHide extends SerialTask<Object, Void, Void> {
public class MagiskHide extends RootTask<Object, Void, Void> {
private boolean isList = false;
@ -17,7 +17,7 @@ public class MagiskHide extends SerialTask<Object, Void, Void> {
}
@Override
protected Void doInBackground(Object... params) {
protected Void doInRoot(Object... params) {
String command = (String) params[0];
List<String> ret = Shell.su("magiskhide --" + command);
if (isList) {
@ -31,6 +31,7 @@ public class MagiskHide extends SerialTask<Object, Void, Void> {
if (isList) {
magiskManager.magiskHideDone.trigger();
}
super.onPostExecute(v);
}
public void add(CharSequence packageName) {

View File

@ -7,9 +7,12 @@ import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Utils;
public abstract class ParallelTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
protected Activity activity;
protected MagiskManager magiskManager;
private Runnable callback = null;
public ParallelTask() {}
public ParallelTask(Activity context) {
@ -17,8 +20,18 @@ public abstract class ParallelTask<Params, Progress, Result> extends AsyncTask<P
magiskManager = Utils.getMagiskManager(context);
}
@SafeVarargs
public final void exec(Params... params) {
@SuppressWarnings("unchecked")
public void exec(Params... params) {
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
}
@Override
protected void onPostExecute(Result result) {
if (callback != null) callback.run();
}
public ParallelTask<Params, Progress, Result> setCallBack(Runnable next) {
callback = next;
return this;
}
}

View File

@ -33,13 +33,13 @@ public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
if (Shell.rootAccess()) {
// Running in parallel mode, open new shell
Shell.su(true,
"rm -f /dev/.magisk",
(mBoot != null) ? "echo \"BOOTIMAGE=/dev/block/" + mBoot + "\" >> /dev/.magisk" : "",
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk"
);
synchronized (Shell.lock) {
Shell.su("rm -f /dev/.magisk",
(mBoot != null) ? "echo \"BOOTIMAGE=" + mBoot + "\" >> /dev/.magisk" : "",
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk"
);
}
return true;
}
return false;
@ -53,5 +53,6 @@ public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
} else {
Utils.showUriSnack(activity, mUri);
}
super.onPostExecute(result);
}
}

View File

@ -0,0 +1,33 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import com.topjohnwu.magisk.utils.Shell;
public abstract class RootTask <Params, Progress, Result> extends ParallelTask<Params, Progress, Result> {
public RootTask() {}
public RootTask(Activity context) {
super(context);
}
@SafeVarargs
@Override
final protected Result doInBackground(Params... params) {
synchronized (Shell.lock) {
return doInRoot(params);
}
}
@SuppressWarnings("unchecked")
abstract protected Result doInRoot(Params... params);
@SuppressWarnings("unchecked")
@Override
public void exec(Params... params) {
if (Shell.rootAccess()) {
super.exec(params);
}
}
}

View File

@ -1,30 +0,0 @@
package com.topjohnwu.magisk.asyncs;
import android.app.Activity;
import android.os.AsyncTask;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.Utils;
/**
* This class is only used for running root commands
**/
public abstract class SerialTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
protected Activity activity;
protected MagiskManager magiskManager;
public SerialTask() {}
public SerialTask(Activity context) {
activity = context;
magiskManager = Utils.getMagiskManager(context);
}
@SafeVarargs
public final void exec(Params... params) {
if (!Shell.rootAccess()) return;
executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);
}
}

View File

@ -33,11 +33,13 @@ public class Module extends BaseModule {
}
public void createDisableFile() {
mEnable = !Utils.createFile(mDisableFile);
mEnable = false;
Utils.createFile(mDisableFile);
}
public void removeDisableFile() {
mEnable = Utils.removeItem(mDisableFile);
mEnable = true;
Utils.removeItem(mDisableFile);
}
public boolean isEnabled() {
@ -45,11 +47,13 @@ public class Module extends BaseModule {
}
public void createRemoveFile() {
mRemove = Utils.createFile(mRemoveFile);
mRemove = true;
Utils.createFile(mRemoveFile);
}
public void deleteRemoveFile() {
mRemove = !Utils.removeItem(mRemoveFile);
mRemove = false;
Utils.removeItem(mRemoveFile);
}
public boolean willBeRemoved() {

View File

@ -1,5 +1,7 @@
package com.topjohnwu.magisk.utils;
import com.topjohnwu.magisk.asyncs.RootTask;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@ -14,6 +16,7 @@ public class Shell {
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
public static int rootStatus;
public static final Object lock = new Object();
private static boolean isInit = false;
private static Process rootShell;
@ -212,4 +215,15 @@ public class Shell {
return new ArrayList<>(res);
}
public static void su_async(List<String> result, String... commands) {
new RootTask<Void, Void, Void>() {
@Override
protected Void doInRoot(Void... params) {
List<String> ret = Shell.su(commands);
if (result != null) result.addAll(ret);
return null;
}
}.exec();
}
}

View File

@ -39,23 +39,15 @@ public class Utils {
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
}
public static boolean commandExists(String s) {
String command = "if [ -z $(which " + s + ") ]; then echo false; else echo true; fi";
List<String> ret = Shell.sh(command);
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
}
public static boolean createFile(String path) {
public static void createFile(String path) {
String folder = path.substring(0, path.lastIndexOf('/'));
String command = "mkdir -p " + folder + " 2>/dev/null; touch " + path + " 2>/dev/null; if [ -f \"" + path + "\" ]; then echo true; else echo false; fi";
List<String> ret = Shell.su(command);
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
Shell.su_async(null, command);
}
public static boolean removeItem(String path) {
public static void removeItem(String path) {
String command = "rm -rf " + path + " 2>/dev/null; if [ -e " + path + " ]; then echo false; else echo true; fi";
List<String> ret = Shell.su(command);
return isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(0));
Shell.su_async(null, command);
}
public static List<String> getModList(String path) {
@ -116,7 +108,7 @@ public class Utils {
"BOOTIMAGE=`readlink /dev/block/by-name/$PARTITION || readlink /dev/block/platform/*/by-name/$PARTITION || readlink /dev/block/platform/*/*/by-name/$PARTITION`",
"if [ ! -z \"$BOOTIMAGE\" ]; then break; fi",
"done",
"echo \"${BOOTIMAGE##*/}\""
"echo \"$BOOTIMAGE\""
};
List<String> ret = Shell.su(commands);
if (isValidShellResponse(ret)) {