mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-26 11:27:38 +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() {
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"))
|
||||||
|
@ -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);
|
||||||
|
@ -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";
|
||||||
|
@ -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) {
|
||||||
|
@ -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";
|
||||||
|
@ -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";
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user