mirror of
https://github.com/topjohnwu/Magisk
synced 2025-11-10 02:12:30 +01:00
Compare commits
57 Commits
manager-v5
...
manager-v5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f38579529 | ||
|
|
4d5a9f6e15 | ||
|
|
41f47acd76 | ||
|
|
821dcaa7c7 | ||
|
|
7135d26419 | ||
|
|
f7fd354dce | ||
|
|
0c69a65bc4 | ||
|
|
2f2ca5eab4 | ||
|
|
df9c40c035 | ||
|
|
25b67017e4 | ||
|
|
bc9c3346f3 | ||
|
|
1db7e19fe8 | ||
|
|
102c03ce2b | ||
|
|
ec19eb4455 | ||
|
|
6d9924d50e | ||
|
|
16c4d74274 | ||
|
|
e4af5fd36a | ||
|
|
702775493a | ||
|
|
b2ae826066 | ||
|
|
cc3e9990fa | ||
|
|
271cbddd5e | ||
|
|
c1423ca9ad | ||
|
|
74379150a1 | ||
|
|
c840a30c30 | ||
|
|
ae5277a898 | ||
|
|
bffa837825 | ||
|
|
b9e7d0faea | ||
|
|
860b08d9ed | ||
|
|
691dc1d49e | ||
|
|
9d6886d367 | ||
|
|
9589b68f5a | ||
|
|
28d88af1af | ||
|
|
8b5acd1849 | ||
|
|
33dc63a7fd | ||
|
|
d0a86385b7 | ||
|
|
50a49e2c8c | ||
|
|
c60adb113e | ||
|
|
aee015e8f6 | ||
|
|
bf6af29205 | ||
|
|
329905d472 | ||
|
|
00d450d262 | ||
|
|
2365d1bd20 | ||
|
|
5b385c18e5 | ||
|
|
98c0434ec0 | ||
|
|
f318d0a3bc | ||
|
|
27f5b410c0 | ||
|
|
3f55be9676 | ||
|
|
b05d2d3a2d | ||
|
|
19af5f9e0b | ||
|
|
f37f330670 | ||
|
|
40082d4571 | ||
|
|
00d655f346 | ||
|
|
821726e7c0 | ||
|
|
759e905c3c | ||
|
|
8bf7e42913 | ||
|
|
0dcd073554 | ||
|
|
2fe35d578d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,7 +6,7 @@
|
|||||||
app/release
|
app/release
|
||||||
*.hprof
|
*.hprof
|
||||||
.externalNativeBuild/
|
.externalNativeBuild/
|
||||||
*.sh
|
src/main/assets
|
||||||
public.certificate.x509.pem
|
public.certificate.x509.pem
|
||||||
private.key.pk8
|
private.key.pk8
|
||||||
*.apk
|
*.apk
|
||||||
|
|||||||
17
build.gradle
17
build.gradle
@@ -8,12 +8,8 @@ android {
|
|||||||
applicationId "com.topjohnwu.magisk"
|
applicationId "com.topjohnwu.magisk"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 90
|
versionCode 105
|
||||||
versionName "5.5.4"
|
versionName "5.6.1"
|
||||||
ndk {
|
|
||||||
moduleName 'zipadjust'
|
|
||||||
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
|
||||||
}
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
argument('butterknife.debuggable', 'false')
|
argument('butterknife.debuggable', 'false')
|
||||||
@@ -36,11 +32,6 @@ android {
|
|||||||
preDexLibraries true
|
preDexLibraries true
|
||||||
javaMaxHeapSize "2g"
|
javaMaxHeapSize "2g"
|
||||||
}
|
}
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
path 'src/main/jni/CMakeLists.txt'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
disable 'MissingTranslation'
|
disable 'MissingTranslation'
|
||||||
}
|
}
|
||||||
@@ -54,7 +45,8 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation project(':crypto')
|
implementation project(':utils')
|
||||||
|
implementation 'com.github.topjohnwu:libsu:1.1.1'
|
||||||
implementation 'com.android.support:recyclerview-v7:27.0.2'
|
implementation 'com.android.support:recyclerview-v7:27.0.2'
|
||||||
implementation 'com.android.support:cardview-v7:27.0.2'
|
implementation 'com.android.support:cardview-v7:27.0.2'
|
||||||
implementation 'com.android.support:design:27.0.2'
|
implementation 'com.android.support:design:27.0.2'
|
||||||
@@ -62,6 +54,5 @@ dependencies {
|
|||||||
implementation 'com.jakewharton:butterknife:8.8.1'
|
implementation 'com.jakewharton:butterknife:8.8.1'
|
||||||
implementation 'com.atlassian.commonmark:commonmark:0.10.0'
|
implementation 'com.atlassian.commonmark:commonmark:0.10.0'
|
||||||
implementation 'org.kamranzafar:jtar:2.3'
|
implementation 'org.kamranzafar:jtar:2.3'
|
||||||
implementation 'com.google.code.gson:gson:2.8.2'
|
|
||||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
||||||
}
|
}
|
||||||
|
|||||||
4
proguard-rules.pro
vendored
4
proguard-rules.pro
vendored
@@ -20,7 +20,9 @@
|
|||||||
-keepnames class ** { *; }
|
-keepnames class ** { *; }
|
||||||
|
|
||||||
# BouncyCastle
|
# BouncyCastle
|
||||||
-keep class org.bouncycastle.jcajce.provider.** { *; }
|
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.**SHA1** { *; }
|
||||||
|
-keep class org.bouncycastle.jcajce.provider.asymmetric.RSA** { *; }
|
||||||
|
-keep class org.bouncycastle.jcajce.provider.digest.SHA1** { *; }
|
||||||
-dontwarn javax.naming.**
|
-dontwarn javax.naming.**
|
||||||
|
|
||||||
# Gson
|
# Gson
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MagiskManager"
|
android:name=".MagiskManager"
|
||||||
android:allowBackup="true"
|
android:allowBackup="false"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
### v5.5.4
|
|
||||||
- Fix on-boot dtbo detection
|
|
||||||
- Add fingerprint authentication for Superuser requests
|
|
||||||
@@ -14,8 +14,6 @@ import com.topjohnwu.magisk.components.AboutCardRow;
|
|||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
@@ -56,12 +54,8 @@ public class AboutActivity extends Activity {
|
|||||||
|
|
||||||
appChangelog.removeSummary();
|
appChangelog.removeSummary();
|
||||||
appChangelog.setOnClickListener(v -> {
|
appChangelog.setOnClickListener(v -> {
|
||||||
try {
|
new MarkDownWindow(this, getString(R.string.app_changelog),
|
||||||
InputStream is = getAssets().open("changelog.md");
|
getResources().openRawResource(R.raw.changelog)).exec();
|
||||||
new MarkDownWindow(this, getString(R.string.app_changelog), is).exec();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
String translators = getString(R.string.translators);
|
String translators = getString(R.string.translators);
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import android.widget.Toast;
|
|||||||
import com.topjohnwu.magisk.asyncs.FlashZip;
|
import com.topjohnwu.magisk.asyncs.FlashZip;
|
||||||
import com.topjohnwu.magisk.asyncs.InstallMagisk;
|
import com.topjohnwu.magisk.asyncs.InstallMagisk;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.container.CallbackList;
|
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.superuser.CallbackList;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@@ -49,7 +49,7 @@ public class FlashActivity extends Activity {
|
|||||||
|
|
||||||
@OnClick(R.id.reboot)
|
@OnClick(R.id.reboot)
|
||||||
void reboot() {
|
void reboot() {
|
||||||
Shell.su_raw("/system/bin/reboot");
|
Shell.Async.su("/system/bin/reboot");
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.save_logs)
|
@OnClick(R.id.save_logs)
|
||||||
@@ -96,10 +96,10 @@ public class FlashActivity extends Activity {
|
|||||||
reboot.setVisibility(View.GONE);
|
reboot.setVisibility(View.GONE);
|
||||||
|
|
||||||
logs = new ArrayList<>();
|
logs = new ArrayList<>();
|
||||||
List<String> console = new CallbackList<String>() {
|
CallbackList<String> console = new CallbackList<String>(new ArrayList<>()) {
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onAddElement(String e) {
|
public void onAddElement(String s) {
|
||||||
logs.add(e);
|
logs.add(s);
|
||||||
flashLogs.setText(TextUtils.join("\n", this));
|
flashLogs.setText(TextUtils.join("\n", this));
|
||||||
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
|
sv.postDelayed(() -> sv.fullScroll(ScrollView.FOCUS_DOWN), 10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
|||||||
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
||||||
import com.topjohnwu.magisk.components.ExpandableView;
|
import com.topjohnwu.magisk.components.ExpandableView;
|
||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.ShowUI;
|
import com.topjohnwu.magisk.utils.ShowUI;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import butterknife.BindColor;
|
import butterknife.BindColor;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
|
|||||||
@@ -21,8 +21,9 @@ import com.topjohnwu.magisk.asyncs.ParallelTask;
|
|||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.CallbackList;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@@ -113,12 +114,18 @@ public class MagiskLogFragment extends Fragment {
|
|||||||
mode = (int) params[0];
|
mode = (int) params[0];
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 0:
|
case 0:
|
||||||
StringBuildingList logList = new StringBuildingList();
|
StringBuilder builder = new StringBuilder();
|
||||||
Shell.su(logList, "cat " + Const.MAGISK_LOG + " | tail -n 5000");
|
CallbackList<String> logs = new CallbackList<String>() {
|
||||||
return logList.getCharSequence();
|
@Override
|
||||||
|
public void onAddElement(String s) {
|
||||||
|
builder.append(s).append('\n');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Shell.Sync.su(logs, "cat " + Const.MAGISK_LOG + " | tail -n 5000");
|
||||||
|
return builder;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
Shell.su_raw("echo -n > " + Const.MAGISK_LOG);
|
Shell.Async.su("echo -n > " + Const.MAGISK_LOG);
|
||||||
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
@@ -138,8 +145,16 @@ public class MagiskLogFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (FileWriter out = new FileWriter(targetFile)) {
|
try (FileWriter out = new FileWriter(targetFile)) {
|
||||||
FileWritingList fileWritingList = new FileWritingList(out);
|
CallbackList<String> list = new CallbackList<String>() {
|
||||||
Shell.su(fileWritingList, "cat " + Const.MAGISK_LOG);
|
@Override
|
||||||
|
public void onAddElement(String s) {
|
||||||
|
try {
|
||||||
|
out.write(s);
|
||||||
|
out.write("\n");
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Shell.Sync.su(list, "cat " + Const.MAGISK_LOG);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
@@ -187,41 +202,4 @@ public class MagiskLogFragment extends Fragment {
|
|||||||
exec(2);
|
exec(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StringBuildingList extends Shell.AbstractList<String> {
|
|
||||||
|
|
||||||
StringBuilder builder;
|
|
||||||
|
|
||||||
StringBuildingList() {
|
|
||||||
builder = new StringBuilder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(String s) {
|
|
||||||
builder.append(s).append("\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharSequence getCharSequence() {
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class FileWritingList extends Shell.AbstractList<String> {
|
|
||||||
|
|
||||||
private FileWriter writer;
|
|
||||||
|
|
||||||
FileWritingList(FileWriter out) {
|
|
||||||
writer = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(String s) {
|
|
||||||
try {
|
|
||||||
writer.write(s + "\n");
|
|
||||||
} catch (IOException ignored) {}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.job.JobInfo;
|
||||||
|
import android.app.job.JobScheduler;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
@@ -8,22 +10,29 @@ import android.content.res.Configuration;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.container.Module;
|
import com.topjohnwu.magisk.container.Module;
|
||||||
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
||||||
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
import com.topjohnwu.magisk.database.SuDatabaseHelper;
|
||||||
|
import com.topjohnwu.magisk.services.UpdateCheckService;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.BusyBox;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class MagiskManager extends Application {
|
public class MagiskManager extends Shell.ContainerApp {
|
||||||
|
|
||||||
// Global weak reference to self
|
// Global weak reference to self
|
||||||
private static WeakReference<MagiskManager> weakSelf;
|
private static WeakReference<MagiskManager> weakSelf;
|
||||||
@@ -78,7 +87,6 @@ public class MagiskManager extends Application {
|
|||||||
public SharedPreferences prefs;
|
public SharedPreferences prefs;
|
||||||
public SuDatabaseHelper suDB;
|
public SuDatabaseHelper suDB;
|
||||||
public RepoDatabaseHelper repoDB;
|
public RepoDatabaseHelper repoDB;
|
||||||
public Shell shell;
|
|
||||||
public Runnable permissionGrantCallback = null;
|
public Runnable permissionGrantCallback = null;
|
||||||
|
|
||||||
private static Handler mHandler = new Handler();
|
private static Handler mHandler = new Handler();
|
||||||
@@ -90,6 +98,26 @@ public class MagiskManager extends Application {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
|
Shell.setFlags(Shell.FLAG_MOUNT_MASTER);
|
||||||
|
Shell.verboseLogging(BuildConfig.DEBUG);
|
||||||
|
BusyBox.BB_PATH = new File(Const.BUSYBOX_PATH);
|
||||||
|
Shell.setInitializer(new Shell.Initializer() {
|
||||||
|
@Override
|
||||||
|
public void onRootShellInit(@NonNull Shell shell) {
|
||||||
|
try (InputStream utils = getAssets().open(Const.UTIL_FUNCTIONS);
|
||||||
|
InputStream sudb = getResources().openRawResource(R.raw.sudb)) {
|
||||||
|
shell.loadInputStream(null, null, utils);
|
||||||
|
shell.loadInputStream(null, null, sudb);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
shell.run(null, null,
|
||||||
|
"mount_partitions",
|
||||||
|
"run_migrations");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
// Handle duplicate package
|
// Handle duplicate package
|
||||||
@@ -103,7 +131,15 @@ public class MagiskManager extends Application {
|
|||||||
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
} catch (PackageManager.NameNotFoundException ignored) { /* Expected */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
suDB = SuDatabaseHelper.getSuDB(false);
|
suDB = SuDatabaseHelper.getInstance(this);
|
||||||
|
|
||||||
|
String pkg = suDB.getStrings(Const.Key.SU_REQUESTER, Const.ORIG_PKG_NAME);
|
||||||
|
if (getPackageName().equals(Const.ORIG_PKG_NAME) && !pkg.equals(Const.ORIG_PKG_NAME)) {
|
||||||
|
suDB.setStrings(Const.Key.SU_REQUESTER, null);
|
||||||
|
Utils.uninstallPkg(pkg);
|
||||||
|
suDB = SuDatabaseHelper.getInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
repoDB = new RepoDatabaseHelper(this);
|
repoDB = new RepoDatabaseHelper(this);
|
||||||
defaultLocale = Locale.getDefault();
|
defaultLocale = Locale.getDefault();
|
||||||
setLocale();
|
setLocale();
|
||||||
@@ -147,8 +183,8 @@ public class MagiskManager extends Application {
|
|||||||
prefs.edit()
|
prefs.edit()
|
||||||
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
|
.putBoolean(Const.Key.DARK_THEME, isDarkTheme)
|
||||||
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
|
.putBoolean(Const.Key.MAGISKHIDE, magiskHide)
|
||||||
.putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE()))
|
.putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE().exists())
|
||||||
.putBoolean(Const.Key.COREONLY, Utils.itemExist(Const.MAGISK_DISABLE_FILE))
|
.putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists())
|
||||||
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
|
.putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout))
|
||||||
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
|
.putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType))
|
||||||
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
|
.putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType))
|
||||||
@@ -172,72 +208,45 @@ public class MagiskManager extends Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void loadMagiskInfo() {
|
public void loadMagiskInfo() {
|
||||||
List<String> ret;
|
|
||||||
ret = Shell.sh("magisk -v");
|
|
||||||
if (!Utils.isValidShellResponse(ret)) {
|
|
||||||
ret = Shell.sh("getprop magisk.version");
|
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
|
||||||
try {
|
try {
|
||||||
magiskVersionString = ret.get(0);
|
magiskVersionString = Utils.cmd("magisk -v").split(":")[0];
|
||||||
magiskVersionCode = (int) Double.parseDouble(ret.get(0)) * 10;
|
magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V"));
|
||||||
} catch (NumberFormatException ignored) {}
|
String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ")
|
||||||
}
|
+ Const.MAGISKHIDE_PROP);
|
||||||
} else {
|
magiskHide = s == null || Integer.parseInt(s) != 0;
|
||||||
magiskVersionString = ret.get(0).split(":")[0];
|
} catch (Exception ignored) {}
|
||||||
ret = Shell.sh("magisk -V");
|
|
||||||
try {
|
|
||||||
magiskVersionCode = Integer.parseInt(ret.get(0));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
|
||||||
if (magiskVersionCode > 1435) {
|
|
||||||
ret = Shell.su("resetprop -p " + Const.MAGISKHIDE_PROP);
|
|
||||||
} else {
|
|
||||||
ret = Shell.sh("getprop " + Const.MAGISKHIDE_PROP);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
magiskHide = !Utils.isValidShellResponse(ret) || Integer.parseInt(ret.get(0)) != 0;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
magiskHide = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = Shell.su("echo \"$BOOTIMAGE\"");
|
bootBlock = Utils.cmd("echo \"$BOOTIMAGE\"");
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
bootBlock = ret.get(0);
|
|
||||||
|
|
||||||
if (suDB != null && !SuDatabaseHelper.verified) {
|
|
||||||
suDB.close();
|
|
||||||
suDB = SuDatabaseHelper.getSuDB(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getDefaultInstallFlags() {
|
public void getDefaultInstallFlags() {
|
||||||
List<String> ret;
|
keepVerity = Boolean.parseBoolean(Utils.cmd("getvar KEEPVERITY; echo $KEEPVERITY")) ||
|
||||||
ret = Shell.su("echo \"$DTBOIMAGE\"");
|
Utils.cmd("echo \"$DTBOIMAGE\"") != null;
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
keepVerity = true;
|
|
||||||
|
|
||||||
ret = Shell.su(
|
keepEnc = Boolean.parseBoolean(Utils.cmd("getvar KEEPFORCEENCRYPT; echo $KEEPFORCEENCRYPT")) ||
|
||||||
"getvar KEEPVERITY",
|
TextUtils.equals("encrypted", Utils.cmd("getprop ro.crypto.state"));
|
||||||
"echo $KEEPVERITY");
|
|
||||||
try {
|
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
keepVerity = Boolean.parseBoolean(ret.get(0));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
|
|
||||||
ret = Shell.sh("getprop ro.crypto.state");
|
|
||||||
if (Utils.isValidShellResponse(ret) && ret.get(0).equals("encrypted"))
|
|
||||||
keepEnc = true;
|
|
||||||
|
|
||||||
ret = Shell.su(
|
|
||||||
"getvar KEEPFORCEENCRYPT",
|
|
||||||
"echo $KEEPFORCEENCRYPT");
|
|
||||||
try {
|
|
||||||
if (Utils.isValidShellResponse(ret))
|
|
||||||
keepEnc = Boolean.parseBoolean(ret.get(0));
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPermissionGrantCallback(Runnable callback) {
|
public void setPermissionGrantCallback(Runnable callback) {
|
||||||
permissionGrantCallback = callback;
|
permissionGrantCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setupUpdateCheck() {
|
||||||
|
JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
|
||||||
|
|
||||||
|
if (prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) {
|
||||||
|
if (scheduler.getAllPendingJobs().isEmpty() ||
|
||||||
|
Const.UPDATE_SERVICE_VER > prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
|
||||||
|
ComponentName service = new ComponentName(this, UpdateCheckService.class);
|
||||||
|
JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
|
||||||
|
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
||||||
|
.setPersisted(true)
|
||||||
|
.setPeriodic(8 * 60 * 60 * 1000)
|
||||||
|
.build();
|
||||||
|
scheduler.schedule(info);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scheduler.cancel(Const.UPDATE_SERVICE_VER);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,9 @@ import android.view.View;
|
|||||||
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
|
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
@@ -99,12 +96,8 @@ public class MainActivity extends Activity
|
|||||||
|
|
||||||
if (mm.prefs.getInt(Const.Key.APP_VER, -1) < BuildConfig.VERSION_CODE) {
|
if (mm.prefs.getInt(Const.Key.APP_VER, -1) < BuildConfig.VERSION_CODE) {
|
||||||
prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply();
|
prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply();
|
||||||
try {
|
new MarkDownWindow(this, getString(R.string.app_changelog),
|
||||||
InputStream is = getAssets().open("changelog.md");
|
getResources().openRawResource(R.raw.changelog)).exec();
|
||||||
new MarkDownWindow(this, getString(R.string.app_changelog), is).exec();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import com.topjohnwu.magisk.asyncs.LoadModules;
|
|||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
import com.topjohnwu.magisk.container.Module;
|
import com.topjohnwu.magisk.container.Module;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -113,16 +113,16 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber {
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.reboot:
|
case R.id.reboot:
|
||||||
Shell.su_raw("/system/bin/reboot");
|
Shell.Async.su("/system/bin/reboot");
|
||||||
return true;
|
return true;
|
||||||
case R.id.reboot_recovery:
|
case R.id.reboot_recovery:
|
||||||
Shell.su_raw("/system/bin/reboot recovery");
|
Shell.Async.su("/system/bin/reboot recovery");
|
||||||
return true;
|
return true;
|
||||||
case R.id.reboot_bootloader:
|
case R.id.reboot_bootloader:
|
||||||
Shell.su_raw("/system/bin/reboot bootloader");
|
Shell.Async.su("/system/bin/reboot bootloader");
|
||||||
return true;
|
return true;
|
||||||
case R.id.reboot_download:
|
case R.id.reboot_download:
|
||||||
Shell.su_raw("/system/bin/reboot download");
|
Shell.Async.su("/system/bin/reboot download");
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -21,12 +22,14 @@ import android.widget.Toast;
|
|||||||
import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
||||||
import com.topjohnwu.magisk.asyncs.HideManager;
|
import com.topjohnwu.magisk.asyncs.HideManager;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
|
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.FingerprintHelper;
|
import com.topjohnwu.magisk.utils.FingerprintHelper;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
@@ -98,6 +101,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
|
PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
|
||||||
PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
|
PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
|
||||||
Preference hideManager = findPreference("hide");
|
Preference hideManager = findPreference("hide");
|
||||||
|
Preference restoreManager = findPreference("restore");
|
||||||
findPreference("clear").setOnPreferenceClickListener((pref) -> {
|
findPreference("clear").setOnPreferenceClickListener((pref) -> {
|
||||||
prefs.edit().remove(Const.Key.ETAG_KEY).apply();
|
prefs.edit().remove(Const.Key.ETAG_KEY).apply();
|
||||||
mm.repoDB.clearRepo();
|
mm.repoDB.clearRepo();
|
||||||
@@ -146,9 +150,42 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
reauth.setSummary(R.string.android_o_not_support);
|
reauth.setSummary(R.string.android_o_not_support);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove fingerprint option if not possible
|
// Disable fingerprint option if not possible
|
||||||
if (!FingerprintHelper.canUseFingerprint()) {
|
if (!FingerprintHelper.canUseFingerprint()) {
|
||||||
suCategory.removePreference(fingerprint);
|
fingerprint.setEnabled(false);
|
||||||
|
fingerprint.setSummary(R.string.disable_fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mm.magiskVersionCode >= 1440) {
|
||||||
|
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
|
||||||
|
hideManager.setOnPreferenceClickListener((pref) -> {
|
||||||
|
Utils.runWithPermission(getActivity(),
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
() -> new HideManager(getActivity()).exec());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
generalCatagory.removePreference(restoreManager);
|
||||||
|
} else {
|
||||||
|
if (Utils.checkNetworkStatus()) {
|
||||||
|
restoreManager.setOnPreferenceClickListener((pref) -> {
|
||||||
|
Utils.runWithPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, () -> {
|
||||||
|
Intent intent = new Intent(mm, ManagerUpdate.class);
|
||||||
|
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
|
||||||
|
intent.putExtra(Const.Key.INTENT_SET_FILENAME,
|
||||||
|
Utils.fmt("MagiskManager-v%s(%d).apk",
|
||||||
|
mm.remoteManagerVersionString, mm.remoteManagerVersionCode));
|
||||||
|
mm.sendBroadcast(intent);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
generalCatagory.removePreference(restoreManager);
|
||||||
|
}
|
||||||
|
generalCatagory.removePreference(hideManager);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generalCatagory.removePreference(restoreManager);
|
||||||
|
generalCatagory.removePreference(hideManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME) && mm.magiskVersionCode >= 1440) {
|
if (mm.getPackageName().equals(Const.ORIG_PKG_NAME) && mm.magiskVersionCode >= 1440) {
|
||||||
@@ -158,6 +195,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
() -> new HideManager(getActivity()).exec());
|
() -> new HideManager(getActivity()).exec());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
generalCatagory.removePreference(restoreManager);
|
||||||
} else {
|
} else {
|
||||||
generalCatagory.removePreference(hideManager);
|
generalCatagory.removePreference(hideManager);
|
||||||
}
|
}
|
||||||
@@ -223,26 +261,28 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
break;
|
break;
|
||||||
case Const.Key.COREONLY:
|
case Const.Key.COREONLY:
|
||||||
if (prefs.getBoolean(key, false)) {
|
if (prefs.getBoolean(key, false)) {
|
||||||
Utils.createFile(Const.MAGISK_DISABLE_FILE);
|
try {
|
||||||
|
Const.MAGISK_DISABLE_FILE.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
} else {
|
} else {
|
||||||
Utils.removeItem(Const.MAGISK_DISABLE_FILE);
|
Const.MAGISK_DISABLE_FILE.delete();
|
||||||
}
|
}
|
||||||
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show();
|
||||||
break;
|
break;
|
||||||
case Const.Key.MAGISKHIDE:
|
case Const.Key.MAGISKHIDE:
|
||||||
if (prefs.getBoolean(key, false)) {
|
if (prefs.getBoolean(key, false)) {
|
||||||
Shell.su_raw("magiskhide --enable");
|
Shell.Async.su("magiskhide --enable");
|
||||||
} else {
|
} else {
|
||||||
Shell.su_raw("magiskhide --disable");
|
Shell.Async.su("magiskhide --disable");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Const.Key.HOSTS:
|
case Const.Key.HOSTS:
|
||||||
if (prefs.getBoolean(key, false)) {
|
if (prefs.getBoolean(key, false)) {
|
||||||
Shell.su_raw(
|
Shell.Async.su(
|
||||||
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(),
|
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(),
|
||||||
"mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts");
|
"mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts");
|
||||||
} else {
|
} else {
|
||||||
Shell.su_raw(
|
Shell.Async.su(
|
||||||
"umount -l /system/etc/hosts",
|
"umount -l /system/etc/hosts",
|
||||||
"rm -f " + Const.MAGISK_HOST_FILE());
|
"rm -f " + Const.MAGISK_HOST_FILE());
|
||||||
}
|
}
|
||||||
@@ -259,6 +299,9 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
case Const.Key.UPDATE_CHANNEL:
|
case Const.Key.UPDATE_CHANNEL:
|
||||||
new CheckUpdates().exec();
|
new CheckUpdates().exec();
|
||||||
break;
|
break;
|
||||||
|
case Const.Key.CHECK_UPDATES:
|
||||||
|
mm.setupUpdateCheck();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mm.loadConfig();
|
mm.loadConfig();
|
||||||
setSummary();
|
setSummary();
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ package com.topjohnwu.magisk;
|
|||||||
|
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.job.JobInfo;
|
|
||||||
import android.app.job.JobScheduler;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -15,10 +11,9 @@ import com.topjohnwu.magisk.asyncs.LoadModules;
|
|||||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||||
import com.topjohnwu.magisk.asyncs.UpdateRepos;
|
import com.topjohnwu.magisk.asyncs.UpdateRepos;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.services.UpdateCheckService;
|
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
public class SplashActivity extends Activity {
|
public class SplashActivity extends Activity {
|
||||||
|
|
||||||
@@ -50,31 +45,18 @@ public class SplashActivity extends Activity {
|
|||||||
LoadModules loadModuleTask = new LoadModules();
|
LoadModules loadModuleTask = new LoadModules();
|
||||||
|
|
||||||
if (Utils.checkNetworkStatus()) {
|
if (Utils.checkNetworkStatus()) {
|
||||||
|
|
||||||
// Fire update check
|
// Fire update check
|
||||||
new CheckUpdates().exec();
|
new CheckUpdates().exec();
|
||||||
|
|
||||||
// Add repo update check
|
// Add repo update check
|
||||||
loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec());
|
loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Magisk working as expected
|
// Magisk working as expected
|
||||||
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
|
if (Shell.rootAccess() && mm.magiskVersionCode > 0) {
|
||||||
|
// Update check service
|
||||||
// Add update checking service
|
mm.setupUpdateCheck();
|
||||||
if (Const.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
|
|
||||||
ComponentName service = new ComponentName(this, UpdateCheckService.class);
|
|
||||||
JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
|
|
||||||
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
|
|
||||||
.setPersisted(true)
|
|
||||||
.setPeriodic(8 * 60 * 60 * 1000)
|
|
||||||
.build();
|
|
||||||
((JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire asynctasks
|
// Fire asynctasks
|
||||||
loadModuleTask.exec();
|
loadModuleTask.exec();
|
||||||
|
|
||||||
// Check dtbo status
|
// Check dtbo status
|
||||||
Utils.patchDTBO();
|
Utils.patchDTBO();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ import com.topjohnwu.magisk.R;
|
|||||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -81,10 +81,10 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
|
|||||||
holder.checkBox.setChecked(mHideList.contains(info.packageName));
|
holder.checkBox.setChecked(mHideList.contains(info.packageName));
|
||||||
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
|
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
Shell.su_raw("magiskhide --add " + info.packageName);
|
Shell.Async.su("magiskhide --add " + info.packageName);
|
||||||
mHideList.add(info.packageName);
|
mHideList.add(info.packageName);
|
||||||
} else {
|
} else {
|
||||||
Shell.su_raw("magiskhide --rm " + info.packageName);
|
Shell.Async.su("magiskhide --rm " + info.packageName);
|
||||||
mHideList.remove(info.packageName);
|
mHideList.remove(info.packageName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -155,7 +155,7 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
|
|||||||
}
|
}
|
||||||
Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
|
Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
|
||||||
.compareTo(b.loadLabel(pm).toString().toLowerCase()));
|
.compareTo(b.loadLabel(pm).toString().toLowerCase()));
|
||||||
mHideList = Shell.su("magiskhide --ls");
|
mHideList = Shell.Sync.su("magiskhide --ls");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import android.widget.TextView;
|
|||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.components.SnackbarMaker;
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
import com.topjohnwu.magisk.container.Module;
|
import com.topjohnwu.magisk.container.Module;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import android.app.Activity;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@@ -32,13 +32,13 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void dlSnet() throws IOException {
|
private void dlSnet() throws IOException {
|
||||||
Shell.sh("rm -rf " + dexPath.getParent());
|
Shell.Sync.sh("rm -rf " + dexPath.getParent());
|
||||||
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
|
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
|
||||||
dexPath.getParentFile().mkdir();
|
dexPath.getParentFile().mkdir();
|
||||||
try (
|
try (
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
|
||||||
InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
}
|
}
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void v) {
|
protected void onPostExecute(Void v) {
|
||||||
MagiskManager mm = MagiskManager.get();
|
MagiskManager mm = MagiskManager.get();
|
||||||
if (showNotification && mm.prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true)) {
|
if (showNotification) {
|
||||||
if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
|
if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) {
|
||||||
ShowUI.managerUpdateNotification();
|
ShowUI.managerUpdateNotification();
|
||||||
} else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {
|
} else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) {
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ import android.view.View;
|
|||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@@ -38,8 +39,8 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
|
|
||||||
private boolean unzipAndCheck() throws Exception {
|
private boolean unzipAndCheck() throws Exception {
|
||||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
||||||
List<String> ret = Utils.readFile(new File(mCachedFile.getParentFile(), "updater-script"));
|
String s = Utils.cmd("head -n 1 " + new File(mCachedFile.getParentFile(), "updater-script"));
|
||||||
return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK");
|
return s != null && s.contains("#MAGISK");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,7 +56,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
) {
|
) {
|
||||||
if (in == null) throw new FileNotFoundException();
|
if (in == null) throw new FileNotFoundException();
|
||||||
InputStream buf= new BufferedInputStream(in);
|
InputStream buf= new BufferedInputStream(in);
|
||||||
Utils.inToOut(buf, out);
|
ShellUtils.pump(buf, out);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
console.add("! Invalid Uri");
|
console.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
@@ -65,7 +66,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
}
|
}
|
||||||
if (!unzipAndCheck()) return 0;
|
if (!unzipAndCheck()) return 0;
|
||||||
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
|
console.add("- Installing " + Utils.getNameFromUri(mm, mUri));
|
||||||
Shell.getShell().run(console, logs,
|
Shell.Sync.su(console, logs,
|
||||||
"cd " + mCachedFile.getParent(),
|
"cd " + mCachedFile.getParent(),
|
||||||
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
|
"BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'"
|
||||||
);
|
);
|
||||||
@@ -85,7 +86,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Integer result) {
|
protected void onPostExecute(Integer result) {
|
||||||
FlashActivity activity = (FlashActivity) getActivity();
|
FlashActivity activity = (FlashActivity) getActivity();
|
||||||
Shell.su_raw(
|
Shell.Async.su(
|
||||||
"rm -rf " + mCachedFile.getParent(),
|
"rm -rf " + mCachedFile.getParent(),
|
||||||
"rm -rf " + Const.TMP_FOLDER_PATH
|
"rm -rf " + Const.TMP_FOLDER_PATH
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import android.app.Activity;
|
|||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.crypto.JarMap;
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
import com.topjohnwu.utils.JarMap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.List;
|
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
|
|
||||||
public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
||||||
@@ -123,19 +123,18 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> {
|
|||||||
apk.getOutputStream(je).write(xml);
|
apk.getOutputStream(je).write(xml);
|
||||||
|
|
||||||
// Sign the APK
|
// Sign the APK
|
||||||
ZipUtils.signZip(apk, repack, false);
|
ZipUtils.signZip(apk, repack);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install the application
|
// Install the application
|
||||||
|
if (!ShellUtils.fastCmdResult(Shell.getShell(), "pm install " + repack))
|
||||||
List<String> ret = Shell.su(Utils.fmt("pm install %s >/dev/null && echo true || echo false", repack));
|
|
||||||
repack.delete();
|
|
||||||
if (!Utils.isValidShellResponse(ret) || !Boolean.parseBoolean(ret.get(0)))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
repack.delete();
|
||||||
|
|
||||||
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg);
|
||||||
Utils.dumpPrefs();
|
Utils.dumpPrefs();
|
||||||
Utils.uninstallPkg(Const.ORIG_PKG_NAME);
|
Utils.uninstallPkg(Const.ORIG_PKG_NAME);
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
package com.topjohnwu.magisk.asyncs;
|
package com.topjohnwu.magisk.asyncs;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.topjohnwu.crypto.SignBoot;
|
|
||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.container.TarEntry;
|
import com.topjohnwu.magisk.container.TarEntry;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||||
|
import com.topjohnwu.utils.SignBoot;
|
||||||
|
|
||||||
import org.kamranzafar.jtar.TarInputStream;
|
import org.kamranzafar.jtar.TarInputStream;
|
||||||
import org.kamranzafar.jtar.TarOutputStream;
|
import org.kamranzafar.jtar.TarOutputStream;
|
||||||
@@ -28,7 +30,6 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
mm.createDeviceProtectedStorageContext() :
|
mm.createDeviceProtectedStorageContext() :
|
||||||
mm).getFilesDir().getParent()
|
mm).getFilesDir().getParent()
|
||||||
, "install");
|
, "install");
|
||||||
Shell.sh_raw("rm -rf " + install);
|
Shell.Sync.sh("rm -rf " + install);
|
||||||
|
|
||||||
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
||||||
String arch;
|
String arch;
|
||||||
@@ -102,16 +103,14 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
console.add("! Cannot unzip zip");
|
console.add("! Cannot unzip zip");
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
Shell.sh("chmod 755 " + install + "/*");
|
Shell.Sync.sh("chmod 755 " + install + "/*");
|
||||||
|
|
||||||
File boot = new File(install, "boot.img");
|
File boot = new File(install, "boot.img");
|
||||||
boolean highCompression = false;
|
boolean highCompression = false;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PATCH_MODE:
|
case PATCH_MODE:
|
||||||
console.add("- Use boot image: " + boot);
|
|
||||||
// Copy boot image to local
|
// Copy boot image to local
|
||||||
try (
|
try (InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
||||||
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
|
||||||
OutputStream out = new FileOutputStream(boot)
|
OutputStream out = new FileOutputStream(boot)
|
||||||
) {
|
) {
|
||||||
InputStream source;
|
InputStream source;
|
||||||
@@ -130,7 +129,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
// Direct copy raw image
|
// Direct copy raw image
|
||||||
source = new BufferedInputStream(in);
|
source = new BufferedInputStream(in);
|
||||||
}
|
}
|
||||||
Utils.inToOut(source, out);
|
ShellUtils.pump(source, out);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
console.add("! Invalid Uri");
|
console.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
@@ -140,21 +139,16 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
console.add("- Use boot image: " + mBootLocation);
|
console.add("- Patch boot/ramdisk image: " + mBootLocation);
|
||||||
if (mm.remoteMagiskVersionCode >= 1463) {
|
if (mm.remoteMagiskVersionCode >= 1463) {
|
||||||
List<String> ret = new ArrayList<>();
|
highCompression = Integer.parseInt(Utils.cmd(Utils.fmt(
|
||||||
Shell.getShell().run(ret, logs,
|
"%s/magiskboot --parse %s; echo $?",
|
||||||
install + "/magiskboot --parse " + mBootLocation,
|
install, mBootLocation))) == 2;
|
||||||
"echo $?"
|
|
||||||
);
|
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
|
||||||
highCompression = Integer.parseInt(ret.get(ret.size() - 1)) == 2;
|
|
||||||
if (highCompression)
|
if (highCompression)
|
||||||
console.add("! Insufficient boot partition size detected");
|
console.add("! Insufficient boot partition size detected");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (boot.createNewFile()) {
|
if (boot.createNewFile()) {
|
||||||
Shell.su("cat " + mBootLocation + " > " + boot);
|
Shell.Sync.su("cat " + mBootLocation + " > " + boot);
|
||||||
} else {
|
} else {
|
||||||
console.add("! Dump boot image failed");
|
console.add("! Dump boot image failed");
|
||||||
return false;
|
return false;
|
||||||
@@ -168,22 +162,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
try (InputStream in = new FileInputStream(boot)) {
|
try (InputStream in = new FileInputStream(boot)) {
|
||||||
isSigned = SignBoot.verifySignature(in, null);
|
isSigned = SignBoot.verifySignature(in, null);
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
console.add("- Signed boot image detected");
|
console.add("- Boot image is signed with AVB 1.0");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
console.add("! Unable to check signature");
|
console.add("! Unable to check signature");
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force non-root shell
|
|
||||||
Shell shell;
|
|
||||||
if (Shell.rootAccess())
|
|
||||||
shell = new Shell("sh");
|
|
||||||
else
|
|
||||||
shell = Shell.getShell();
|
|
||||||
|
|
||||||
// Patch boot image
|
// Patch boot image
|
||||||
shell.run(console, logs,
|
Shell.Sync.sh(console, logs,
|
||||||
"cd " + install,
|
"cd " + install,
|
||||||
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " +
|
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " +
|
||||||
"sh update-binary indep boot_patch.sh %s || echo 'Failed!'",
|
"sh update-binary indep boot_patch.sh %s || echo 'Failed!'",
|
||||||
@@ -192,27 +179,22 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
|
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
shell.run(null, null,
|
Shell.Sync.sh("mv -f new-boot.img ../",
|
||||||
"mv -f new-boot.img ../",
|
|
||||||
"mv bin/busybox busybox",
|
"mv bin/busybox busybox",
|
||||||
"rm -rf bin *.img update-binary",
|
"rm -rf bin *.img update-binary",
|
||||||
"cd /");
|
"cd /");
|
||||||
|
|
||||||
File patched_boot = new File(install.getParent(), "new-boot.img");
|
SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img");
|
||||||
|
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
console.add("- Signing boot image");
|
console.add("- Signing boot image with test keys");
|
||||||
File signed = new File(install.getParent(), "signed.img");
|
File signed = new File(install.getParent(), "signed.img");
|
||||||
AssetManager assets = mm.getAssets();
|
try (InputStream in = new SuFileInputStream(patched_boot);
|
||||||
try (
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
|
||||||
InputStream in = new FileInputStream(patched_boot);
|
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed));
|
|
||||||
InputStream keyIn = assets.open(Const.PRIVATE_KEY_NAME);
|
|
||||||
InputStream certIn = assets.open(Const.PUBLIC_KEY_NAME)
|
|
||||||
) {
|
) {
|
||||||
SignBoot.doSignature("/boot", in, out, keyIn, certIn);
|
SignBoot.doSignature("/boot", in, out, null, null);
|
||||||
}
|
}
|
||||||
shell.run_raw(false, false, "mv -f " + signed + " " + patched_boot);
|
Shell.Sync.sh("mv -f " + signed + " " + patched_boot);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
@@ -230,8 +212,8 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
out = new BufferedOutputStream(new FileOutputStream(dest));
|
out = new BufferedOutputStream(new FileOutputStream(dest));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try (InputStream in = new BufferedInputStream(new FileInputStream(patched_boot))) {
|
try (InputStream in = new SuFileInputStream(patched_boot)) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
console.add("");
|
console.add("");
|
||||||
@@ -242,7 +224,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk";
|
String binPath = mm.remoteMagiskVersionCode >= 1464 ? "/data/adb/magisk" : "/data/magisk";
|
||||||
Shell.getShell().run(console, logs,
|
Shell.Sync.su(console, logs,
|
||||||
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
|
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
|
||||||
Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install),
|
Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install),
|
||||||
Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation),
|
Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.topjohnwu.magisk.MagiskManager;
|
|||||||
import com.topjohnwu.magisk.container.Module;
|
import com.topjohnwu.magisk.container.Module;
|
||||||
import com.topjohnwu.magisk.container.ValueSortedMap;
|
import com.topjohnwu.magisk.container.ValueSortedMap;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ public class LoadModules extends ParallelTask<Void, Void, Void> {
|
|||||||
|
|
||||||
private List<String> getModList() {
|
private List<String> getModList() {
|
||||||
String command = "ls -d " + Const.MAGISK_PATH() + "/* | grep -v lost+found";
|
String command = "ls -d " + Const.MAGISK_PATH() + "/* | grep -v lost+found";
|
||||||
return Shell.su(command);
|
return Shell.Sync.su(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import android.webkit.WebView;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import org.commonmark.node.Node;
|
import org.commonmark.node.Node;
|
||||||
import org.commonmark.parser.Parser;
|
import org.commonmark.parser.Parser;
|
||||||
@@ -44,7 +44,7 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
|
|||||||
md = WebService.getString(mUrl);
|
md = WebService.getString(mUrl);
|
||||||
} else {
|
} else {
|
||||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||||
Utils.inToOut(is, out);
|
ShellUtils.pump(is, out);
|
||||||
md = out.toString();
|
md = out.toString();
|
||||||
is.close();
|
is.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -54,11 +54,13 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> {
|
|||||||
}
|
}
|
||||||
String css;
|
String css;
|
||||||
try (
|
try (
|
||||||
InputStream in = mm.getAssets().open(mm.isDarkTheme ? "dark.css" : "light.css");
|
InputStream in = mm.getResources().openRawResource(
|
||||||
|
mm.isDarkTheme ? R.raw.dark : R.raw.light);
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
ByteArrayOutputStream out = new ByteArrayOutputStream()
|
||||||
) {
|
) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
css = out.toString();
|
css = out.toString();
|
||||||
|
in.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return "";
|
return "";
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ import com.topjohnwu.magisk.FlashActivity;
|
|||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@@ -68,7 +69,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
out.putNextEntry(new JarEntry(path));
|
out.putNextEntry(new JarEntry(path));
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
|
InputStream in = new BufferedInputStream(new ProgressInputStream(conn.getInputStream()));
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1))
|
||||||
) {
|
) {
|
||||||
Utils.inToOut(in, out);
|
ShellUtils.pump(in, out);
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
@@ -120,14 +121,8 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
// First remove top folder in Github source zip, temp1 -> temp2
|
// First remove top folder in Github source zip, temp1 -> temp2
|
||||||
removeTopFolder(temp1, temp2);
|
removeTopFolder(temp1, temp2);
|
||||||
|
|
||||||
// Then sign the zip for the first time, temp2 -> temp1
|
// Then sign the zip
|
||||||
ZipUtils.signZip(temp2, temp1, false);
|
ZipUtils.signZip(temp2, mFile);
|
||||||
|
|
||||||
// Adjust the zip to prevent unzip issues, temp1 -> temp2
|
|
||||||
ZipUtils.zipAdjust(temp1.getPath(), temp2.getPath());
|
|
||||||
|
|
||||||
// Finally, sign the whole zip file again, temp2 -> target
|
|
||||||
ZipUtils.signZip(temp2, mFile, true);
|
|
||||||
|
|
||||||
// Delete temp files
|
// Delete temp files
|
||||||
temp1.delete();
|
temp1.delete();
|
||||||
|
|||||||
@@ -4,29 +4,24 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
import java.util.List;
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
|
public class RestoreImages extends ParallelTask<Void, Void, Boolean> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... voids) {
|
protected Boolean doInBackground(Void... voids) {
|
||||||
String sha1;
|
String sha1;
|
||||||
List<String> ret = Utils.readFile("/.backup/.sha1");
|
sha1 = Utils.cmd("cat /.backup/.sha1");
|
||||||
if (Utils.isValidShellResponse(ret)) {
|
if (sha1 == null) {
|
||||||
sha1 = ret.get(0);
|
sha1 = Utils.cmd("cat /init.magisk.rc | grep STOCKSHA1");
|
||||||
} else {
|
if (sha1 == null)
|
||||||
ret = Shell.su("cat /init.magisk.rc | grep STOCKSHA1");
|
|
||||||
if (!Utils.isValidShellResponse(ret))
|
|
||||||
return false;
|
return false;
|
||||||
sha1 = ret.get(0).substring(ret.get(0).indexOf('=') + 1);
|
sha1 = sha1.substring(sha1.indexOf('=') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = Shell.su("restore_imgs " + sha1 + " && echo true || echo false");
|
return ShellUtils.fastCmdResult(Shell.getShell(), "restore_imgs " + sha1);
|
||||||
|
|
||||||
return Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.container;
|
|
||||||
|
|
||||||
import android.os.Handler;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public abstract class CallbackList<E> extends ArrayList<E> {
|
|
||||||
|
|
||||||
private Handler handler;
|
|
||||||
|
|
||||||
protected CallbackList() {
|
|
||||||
handler = new Handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void onAddElement(E e);
|
|
||||||
|
|
||||||
public synchronized boolean add(E e) {
|
|
||||||
boolean ret = super.add(e);
|
|
||||||
handler.post(() -> onAddElement(e));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +1,24 @@
|
|||||||
package com.topjohnwu.magisk.container;
|
package com.topjohnwu.magisk.container;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.io.SuFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class Module extends BaseModule {
|
public class Module extends BaseModule {
|
||||||
|
|
||||||
private String mRemoveFile, mDisableFile, mUpdateFile;
|
private SuFile mRemoveFile, mDisableFile, mUpdateFile;
|
||||||
private boolean mEnable, mRemove, mUpdated;
|
private boolean mEnable, mRemove, mUpdated;
|
||||||
|
|
||||||
public Module(String path) {
|
public Module(String path) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
parseProps(Utils.readFile(path + "/module.prop"));
|
parseProps(Shell.Sync.su("cat " + path + "/module.prop"));
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException ignored) {}
|
||||||
|
|
||||||
mRemoveFile = path + "/remove";
|
mRemoveFile = new SuFile(path + "/remove", true);
|
||||||
mDisableFile = path + "/disable";
|
mDisableFile = new SuFile(path + "/disable", true);
|
||||||
mUpdateFile = path + "/update";
|
mUpdateFile = new SuFile(path + "/update", true);
|
||||||
|
|
||||||
if (getId() == null) {
|
if (getId() == null) {
|
||||||
int sep = path.lastIndexOf('/');
|
int sep = path.lastIndexOf('/');
|
||||||
@@ -26,19 +29,21 @@ public class Module extends BaseModule {
|
|||||||
setName(getId());
|
setName(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
mEnable = !Utils.itemExist(mDisableFile);
|
mEnable = !mDisableFile.exists();
|
||||||
mRemove = Utils.itemExist(mRemoveFile);
|
mRemove = mRemoveFile.exists();
|
||||||
mUpdated = Utils.itemExist(mUpdateFile);
|
mUpdated = mUpdateFile.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createDisableFile() {
|
public void createDisableFile() {
|
||||||
mEnable = false;
|
mEnable = false;
|
||||||
Utils.createFile(mDisableFile);
|
try {
|
||||||
|
mDisableFile.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeDisableFile() {
|
public void removeDisableFile() {
|
||||||
mEnable = true;
|
mEnable = true;
|
||||||
Utils.removeItem(mDisableFile);
|
mDisableFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
@@ -47,12 +52,14 @@ public class Module extends BaseModule {
|
|||||||
|
|
||||||
public void createRemoveFile() {
|
public void createRemoveFile() {
|
||||||
mRemove = true;
|
mRemove = true;
|
||||||
Utils.createFile(mRemoveFile);
|
try {
|
||||||
|
mRemoveFile.createNewFile();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteRemoveFile() {
|
public void deleteRemoveFile() {
|
||||||
mRemove = false;
|
mRemove = false;
|
||||||
Utils.removeItem(mRemoveFile);
|
mRemoveFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean willBeRemoved() {
|
public boolean willBeRemoved() {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@ public class ManagerUpdate extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
intent.getStringExtra(Const.Key.INTENT_SET_LINK),
|
intent.getStringExtra(Const.Key.INTENT_SET_LINK),
|
||||||
Utils.fmt("MagiskManager-v%s.apk", intent.getStringExtra(Const.Key.INTENT_SET_VERSION))
|
intent.getStringExtra(Const.Key.INTENT_SET_FILENAME)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import android.content.Intent;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
public class PackageReceiver extends BroadcastReceiver {
|
public class PackageReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
@@ -25,7 +25,7 @@ public class PackageReceiver extends BroadcastReceiver {
|
|||||||
break;
|
break;
|
||||||
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
|
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
|
||||||
mm.suDB.deletePolicy(pkg);
|
mm.suDB.deletePolicy(pkg);
|
||||||
Shell.su_raw("magiskhide --rm " + pkg);
|
Shell.Async.su("magiskhide --rm " + pkg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
public class RebootReceiver extends BroadcastReceiver {
|
public class RebootReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Shell.su_raw("/system/bin/reboot");
|
Shell.Async.su("/system/bin/reboot");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import android.support.v4.app.NotificationCompat;
|
|||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Shell;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
public class OnBootIntentService extends IntentService {
|
public class OnBootIntentService extends IntentService {
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user