mirror of
				https://github.com/topjohnwu/Magisk
				synced 2025-10-30 09:00:52 +01:00 
			
		
		
		
	Compare commits
	
		
			90 Commits
		
	
	
		
			manager-v5
			...
			manager-v5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d5408d1f09 | ||
|   | f334532aba | ||
|   | be77c09f3d | ||
|   | 7de6a92753 | ||
|   | 36f76f5a14 | ||
|   | b84523d557 | ||
|   | 2c78c415e9 | ||
|   | 79ccb30dd2 | ||
|   | 3c566becf6 | ||
|   | 151ca593af | ||
|   | 4132eacba0 | ||
|   | 06e6151816 | ||
|   | 70277d4edd | ||
|   | d21d2f1a9c | ||
|   | 74a7be996f | ||
|   | 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 | ||
|   | 8d139e156e | ||
|   | 7c2849356a | ||
|   | 0025ffd1c0 | ||
|   | 2ef7146642 | ||
|   | 1b27e69e40 | ||
|   | 8e7b757efd | ||
|   | 1ab543cea1 | ||
|   | a3f86903e4 | ||
|   | c239c305ab | ||
|   | 2e02af994e | ||
|   | 836d9afe17 | ||
|   | 007a352742 | ||
|   | e526e5659e | ||
|   | 4a5227c7bf | ||
|   | c2c151ec4c | ||
|   | 452096e7e4 | ||
|   | 50c2a9859e | ||
|   | 677b667307 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
| app/release | ||||
| *.hprof | ||||
| .externalNativeBuild/ | ||||
| *.sh | ||||
| src/main/assets | ||||
| public.certificate.x509.pem | ||||
| private.key.pk8 | ||||
| *.apk | ||||
|   | ||||
							
								
								
									
										18
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								build.gradle
									
									
									
									
									
								
							| @@ -2,18 +2,13 @@ apply plugin: 'com.android.application' | ||||
|  | ||||
| android { | ||||
|     compileSdkVersion 27 | ||||
|     buildToolsVersion "27.0.3" | ||||
|  | ||||
|     defaultConfig { | ||||
|         applicationId "com.topjohnwu.magisk" | ||||
|         minSdkVersion 21 | ||||
|         targetSdkVersion 27 | ||||
|         versionCode 84 | ||||
|         versionName "5.5.2" | ||||
|         ndk { | ||||
|             moduleName 'zipadjust' | ||||
|             abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' | ||||
|         } | ||||
|         versionCode 108 | ||||
|         versionName "5.6.2" | ||||
|         javaCompileOptions { | ||||
|             annotationProcessorOptions { | ||||
|                 argument('butterknife.debuggable', 'false') | ||||
| @@ -36,11 +31,6 @@ android { | ||||
|         preDexLibraries true | ||||
|         javaMaxHeapSize "2g" | ||||
|     } | ||||
|     externalNativeBuild { | ||||
|         cmake { | ||||
|             path 'src/main/jni/CMakeLists.txt' | ||||
|         } | ||||
|     } | ||||
|     lintOptions { | ||||
|         disable 'MissingTranslation' | ||||
|     } | ||||
| @@ -54,7 +44,8 @@ repositories { | ||||
|  | ||||
| dependencies { | ||||
|     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:cardview-v7:27.0.2' | ||||
|     implementation 'com.android.support:design:27.0.2' | ||||
| @@ -62,6 +53,5 @@ dependencies { | ||||
|     implementation 'com.jakewharton:butterknife:8.8.1' | ||||
|     implementation 'com.atlassian.commonmark:commonmark:0.10.0' | ||||
|     implementation 'org.kamranzafar:jtar:2.3' | ||||
|     implementation 'com.google.code.gson:gson:2.8.2' | ||||
|     annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' | ||||
| } | ||||
|   | ||||
							
								
								
									
										7
									
								
								proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							| @@ -20,5 +20,10 @@ | ||||
| -keepnames class ** { *; } | ||||
|  | ||||
| # 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.** | ||||
|  | ||||
| # Gson | ||||
| -keepattributes Signature | ||||
| @@ -9,10 +9,11 @@ | ||||
|     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> | ||||
|     <uses-permission android:name="android.permission.VIBRATE" /> | ||||
|     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> | ||||
|     <uses-permission android:name="android.permission.USE_FINGERPRINT" /> | ||||
|  | ||||
|     <application | ||||
|         android:name=".MagiskManager" | ||||
|         android:allowBackup="true" | ||||
|         android:allowBackup="false" | ||||
|         android:icon="@mipmap/ic_launcher" | ||||
|         android:roundIcon="@mipmap/ic_launcher_round" | ||||
|         android:label="@string/app_name" | ||||
|   | ||||
| @@ -1,4 +0,0 @@ | ||||
| ### v5.5.2 | ||||
| - Support sorting online repos with last update | ||||
| - Fix issue that advanced installation settings won't stick | ||||
| - Prevent sudb crashing Magisk Manager | ||||
| @@ -14,8 +14,6 @@ import com.topjohnwu.magisk.components.AboutCardRow; | ||||
| import com.topjohnwu.magisk.components.Activity; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.Locale; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| @@ -56,12 +54,8 @@ public class AboutActivity extends Activity { | ||||
|  | ||||
|         appChangelog.removeSummary(); | ||||
|         appChangelog.setOnClickListener(v -> { | ||||
|             try { | ||||
|                 InputStream is = getAssets().open("changelog.md"); | ||||
|                 new MarkDownWindow(this, getString(R.string.app_changelog), is).exec(); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|             new MarkDownWindow(this, getString(R.string.app_changelog), | ||||
|                     getResources().openRawResource(R.raw.changelog)).exec(); | ||||
|         }); | ||||
|  | ||||
|         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.InstallMagisk; | ||||
| import com.topjohnwu.magisk.components.Activity; | ||||
| import com.topjohnwu.magisk.container.CallbackList; | ||||
| 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.FileWriter; | ||||
| @@ -49,7 +49,7 @@ public class FlashActivity extends Activity { | ||||
|  | ||||
|     @OnClick(R.id.reboot) | ||||
|     void reboot() { | ||||
|         Shell.su_raw("/system/bin/reboot"); | ||||
|         Shell.Async.su("/system/bin/reboot"); | ||||
|     } | ||||
|  | ||||
|     @OnClick(R.id.save_logs) | ||||
| @@ -96,10 +96,10 @@ public class FlashActivity extends Activity { | ||||
|             reboot.setVisibility(View.GONE); | ||||
|  | ||||
|         logs = new ArrayList<>(); | ||||
|         List<String> console = new CallbackList<String>() { | ||||
|         CallbackList<String> console = new CallbackList<String>(new ArrayList<>()) { | ||||
|             @Override | ||||
|             public synchronized void onAddElement(String e) { | ||||
|                 logs.add(e); | ||||
|             public void onAddElement(String s) { | ||||
|                 logs.add(s); | ||||
|                 flashLogs.setText(TextUtils.join("\n", this)); | ||||
|                 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.ExpandableView; | ||||
| import com.topjohnwu.magisk.components.Fragment; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.ShowUI; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import butterknife.BindColor; | ||||
| import butterknife.BindView; | ||||
|   | ||||
| @@ -21,8 +21,9 @@ import com.topjohnwu.magisk.asyncs.ParallelTask; | ||||
| import com.topjohnwu.magisk.components.Fragment; | ||||
| import com.topjohnwu.magisk.components.SnackbarMaker; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.CallbackList; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileWriter; | ||||
| @@ -113,12 +114,18 @@ public class MagiskLogFragment extends Fragment { | ||||
|             mode = (int) params[0]; | ||||
|             switch (mode) { | ||||
|                 case 0: | ||||
|                     StringBuildingList logList = new StringBuildingList(); | ||||
|                     Shell.su(logList, "cat " + Const.MAGISK_LOG + " | tail -n 5000"); | ||||
|                     return logList.getCharSequence(); | ||||
|                     StringBuilder builder = new StringBuilder(); | ||||
|                     CallbackList<String> logs = new CallbackList<String>() { | ||||
|                         @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: | ||||
|                     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(); | ||||
|                     return ""; | ||||
|  | ||||
| @@ -138,8 +145,16 @@ public class MagiskLogFragment extends Fragment { | ||||
|                     } | ||||
|  | ||||
|                     try (FileWriter out = new FileWriter(targetFile)) { | ||||
|                         FileWritingList fileWritingList = new FileWritingList(out); | ||||
|                         Shell.su(fileWritingList, "cat " + Const.MAGISK_LOG); | ||||
|                         CallbackList<String> list = new CallbackList<String>() { | ||||
|                             @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) { | ||||
|                         e.printStackTrace(); | ||||
|                         return false; | ||||
| @@ -187,41 +202,4 @@ public class MagiskLogFragment extends Fragment { | ||||
|             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; | ||||
|  | ||||
| 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.SharedPreferences; | ||||
| import android.content.pm.PackageManager; | ||||
| @@ -8,22 +10,29 @@ import android.content.res.Configuration; | ||||
| import android.content.res.Resources; | ||||
| import android.os.Handler; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.text.TextUtils; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import com.topjohnwu.magisk.container.Module; | ||||
| import com.topjohnwu.magisk.database.RepoDatabaseHelper; | ||||
| import com.topjohnwu.magisk.database.SuDatabaseHelper; | ||||
| import com.topjohnwu.magisk.services.UpdateCheckService; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| 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.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.Map; | ||||
|  | ||||
| public class MagiskManager extends Application { | ||||
| public class MagiskManager extends Shell.ContainerApp { | ||||
|  | ||||
|     // Global weak reference to self | ||||
|     private static WeakReference<MagiskManager> weakSelf; | ||||
| @@ -62,8 +71,6 @@ public class MagiskManager extends Application { | ||||
|  | ||||
|     public boolean magiskHide; | ||||
|     public boolean isDarkTheme; | ||||
|     public boolean updateNotification; | ||||
|     public boolean suReauth; | ||||
|     public int suRequestTimeout; | ||||
|     public int suLogTimeout = 14; | ||||
|     public int suAccessState; | ||||
| @@ -74,14 +81,12 @@ public class MagiskManager extends Application { | ||||
|     public String localeConfig; | ||||
|     public int updateChannel; | ||||
|     public String bootFormat; | ||||
|     public String customChannelUrl; | ||||
|     public int repoOrder; | ||||
|  | ||||
|     // Global resources | ||||
|     public SharedPreferences prefs; | ||||
|     public SuDatabaseHelper suDB; | ||||
|     public RepoDatabaseHelper repoDB; | ||||
|     public Shell shell; | ||||
|     public Runnable permissionGrantCallback = null; | ||||
|  | ||||
|     private static Handler mHandler = new Handler(); | ||||
| @@ -93,6 +98,26 @@ public class MagiskManager extends Application { | ||||
|     @Override | ||||
|     public void 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); | ||||
|  | ||||
|         // Handle duplicate package | ||||
| @@ -106,7 +131,15 @@ public class MagiskManager extends Application { | ||||
|             } 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); | ||||
|         defaultLocale = Locale.getDefault(); | ||||
|         setLocale(); | ||||
| @@ -135,17 +168,14 @@ public class MagiskManager extends Application { | ||||
|         suRequestTimeout = Utils.getPrefsInt(prefs, Const.Key.SU_REQUEST_TIMEOUT, Const.Value.timeoutList[2]); | ||||
|         suResponseType = Utils.getPrefsInt(prefs, Const.Key.SU_AUTO_RESPONSE, Const.Value.SU_PROMPT); | ||||
|         suNotificationType = Utils.getPrefsInt(prefs, Const.Key.SU_NOTIFICATION, Const.Value.NOTIFICATION_TOAST); | ||||
|         suReauth = prefs.getBoolean(Const.Key.SU_REAUTH, false); | ||||
|         suAccessState = suDB.getSettings(Const.Key.ROOT_ACCESS, Const.Value.ROOT_ACCESS_APPS_AND_ADB); | ||||
|         multiuserMode = suDB.getSettings(Const.Key.SU_MULTIUSER_MODE, Const.Value.MULTIUSER_MODE_OWNER_ONLY); | ||||
|         suNamespaceMode = suDB.getSettings(Const.Key.SU_MNT_NS, Const.Value.NAMESPACE_MODE_REQUESTER); | ||||
|  | ||||
|         // config | ||||
|         isDarkTheme = prefs.getBoolean(Const.Key.DARK_THEME, false); | ||||
|         updateNotification = prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true); | ||||
|         updateChannel = Utils.getPrefsInt(prefs, Const.Key.UPDATE_CHANNEL, Const.Value.STABLE_CHANNEL); | ||||
|         bootFormat = prefs.getString(Const.Key.BOOT_FORMAT, ".img"); | ||||
|         customChannelUrl = prefs.getString(Const.Key.CUSTOM_CHANNEL, ""); | ||||
|         repoOrder = prefs.getInt(Const.Key.REPO_ORDER, Const.Value.ORDER_NAME); | ||||
|     } | ||||
|  | ||||
| @@ -153,10 +183,8 @@ public class MagiskManager extends Application { | ||||
|         prefs.edit() | ||||
|                 .putBoolean(Const.Key.DARK_THEME, isDarkTheme) | ||||
|                 .putBoolean(Const.Key.MAGISKHIDE, magiskHide) | ||||
|                 .putBoolean(Const.Key.UPDATE_NOTIFICATION, updateNotification) | ||||
|                 .putBoolean(Const.Key.HOSTS, Utils.itemExist(Const.MAGISK_HOST_FILE())) | ||||
|                 .putBoolean(Const.Key.COREONLY, Utils.itemExist(Const.MAGISK_DISABLE_FILE)) | ||||
|                 .putBoolean(Const.Key.SU_REAUTH, suReauth) | ||||
|                 .putBoolean(Const.Key.HOSTS, Const.MAGISK_HOST_FILE().exists()) | ||||
|                 .putBoolean(Const.Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists()) | ||||
|                 .putString(Const.Key.SU_REQUEST_TIMEOUT, String.valueOf(suRequestTimeout)) | ||||
|                 .putString(Const.Key.SU_AUTO_RESPONSE, String.valueOf(suResponseType)) | ||||
|                 .putString(Const.Key.SU_NOTIFICATION, String.valueOf(suNotificationType)) | ||||
| @@ -171,7 +199,7 @@ public class MagiskManager extends Application { | ||||
|                 .apply(); | ||||
|     } | ||||
|  | ||||
|     public static void toast(String msg, int duration) { | ||||
|     public static void toast(CharSequence msg, int duration) { | ||||
|         mHandler.post(() -> Toast.makeText(weakSelf.get(), msg, duration).show()); | ||||
|     } | ||||
|  | ||||
| @@ -180,72 +208,45 @@ public class MagiskManager extends Application { | ||||
|     } | ||||
|  | ||||
|     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 { | ||||
|                     magiskVersionString = ret.get(0); | ||||
|                     magiskVersionCode = (int) Double.parseDouble(ret.get(0)) * 10; | ||||
|                 } catch (NumberFormatException ignored) {} | ||||
|             } | ||||
|         } else { | ||||
|             magiskVersionString = ret.get(0).split(":")[0]; | ||||
|             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; | ||||
|         } | ||||
|             magiskVersionString = Utils.cmd("magisk -v").split(":")[0]; | ||||
|             magiskVersionCode = Integer.parseInt(Utils.cmd("magisk -V")); | ||||
|             String s = Utils.cmd((magiskVersionCode > 1435 ? "resetprop -p " : "getprop ") | ||||
|                     + Const.MAGISKHIDE_PROP); | ||||
|             magiskHide = s == null || Integer.parseInt(s) != 0; | ||||
|         } catch (Exception ignored) {} | ||||
|  | ||||
|         ret = Shell.su("echo \"$BOOTIMAGE\""); | ||||
|         if (Utils.isValidShellResponse(ret)) | ||||
|             bootBlock = ret.get(0); | ||||
|  | ||||
|         if (suDB != null && !SuDatabaseHelper.verified) { | ||||
|             suDB.close(); | ||||
|             suDB = SuDatabaseHelper.getSuDB(true); | ||||
|         } | ||||
|         bootBlock = Utils.cmd("echo \"$BOOTIMAGE\""); | ||||
|     } | ||||
|  | ||||
|     public void getDefaultInstallFlags() { | ||||
|         List<String> ret; | ||||
|         ret = Shell.su("echo \"$DTBOIMAGE\""); | ||||
|         if (Utils.isValidShellResponse(ret)) | ||||
|             keepVerity = true; | ||||
|         keepVerity = Boolean.parseBoolean(Utils.cmd("getvar KEEPVERITY; echo $KEEPVERITY")) || | ||||
|                 Utils.cmd("echo \"$DTBOIMAGE\"") != null; | ||||
|  | ||||
|         ret = Shell.su( | ||||
|                 "getvar KEEPVERITY", | ||||
|                 "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) {} | ||||
|         keepEnc = Boolean.parseBoolean(Utils.cmd("getvar KEEPFORCEENCRYPT; echo $KEEPFORCEENCRYPT")) || | ||||
|                 TextUtils.equals("encrypted", Utils.cmd("getprop ro.crypto.state")); | ||||
|     } | ||||
|  | ||||
|     public void setPermissionGrantCallback(Runnable 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.components.Activity; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| @@ -99,12 +96,8 @@ public class MainActivity extends Activity | ||||
|  | ||||
|         if (mm.prefs.getInt(Const.Key.APP_VER, -1) < BuildConfig.VERSION_CODE) { | ||||
|             prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply(); | ||||
|             try { | ||||
|                 InputStream is = getAssets().open("changelog.md"); | ||||
|                 new MarkDownWindow(this, getString(R.string.app_changelog), is).exec(); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|             new MarkDownWindow(this, getString(R.string.app_changelog), | ||||
|                     getResources().openRawResource(R.raw.changelog)).exec(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -20,9 +20,9 @@ import com.topjohnwu.magisk.asyncs.LoadModules; | ||||
| import com.topjohnwu.magisk.components.Fragment; | ||||
| import com.topjohnwu.magisk.container.Module; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| @@ -113,16 +113,16 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber { | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         switch (item.getItemId()) { | ||||
|             case R.id.reboot: | ||||
|                 Shell.su_raw("/system/bin/reboot"); | ||||
|                 Shell.Async.su("/system/bin/reboot"); | ||||
|                 return true; | ||||
|             case R.id.reboot_recovery: | ||||
|                 Shell.su_raw("/system/bin/reboot recovery"); | ||||
|                 Shell.Async.su("/system/bin/reboot recovery"); | ||||
|                 return true; | ||||
|             case R.id.reboot_bootloader: | ||||
|                 Shell.su_raw("/system/bin/reboot bootloader"); | ||||
|                 Shell.Async.su("/system/bin/reboot bootloader"); | ||||
|                 return true; | ||||
|             case R.id.reboot_download: | ||||
|                 Shell.su_raw("/system/bin/reboot download"); | ||||
|                 Shell.Async.su("/system/bin/reboot download"); | ||||
|                 return true; | ||||
|             default: | ||||
|                 return false; | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package com.topjohnwu.magisk; | ||||
|  | ||||
| import android.Manifest; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| @@ -21,11 +22,14 @@ import android.widget.Toast; | ||||
| import com.topjohnwu.magisk.asyncs.CheckUpdates; | ||||
| import com.topjohnwu.magisk.asyncs.HideManager; | ||||
| import com.topjohnwu.magisk.components.Activity; | ||||
| import com.topjohnwu.magisk.receivers.ManagerUpdate; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.FingerprintHelper; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.util.Locale; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| @@ -97,6 +101,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber { | ||||
|             PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk"); | ||||
|             PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser"); | ||||
|             Preference hideManager = findPreference("hide"); | ||||
|             Preference restoreManager = findPreference("restore"); | ||||
|             findPreference("clear").setOnPreferenceClickListener((pref) -> { | ||||
|                 prefs.edit().remove(Const.Key.ETAG_KEY).apply(); | ||||
|                 mm.repoDB.clearRepo(); | ||||
| @@ -112,13 +117,14 @@ public class SettingsActivity extends Activity implements Topic.Subscriber { | ||||
|             multiuserMode = (ListPreference) findPreference(Const.Key.SU_MULTIUSER_MODE); | ||||
|             namespaceMode = (ListPreference) findPreference(Const.Key.SU_MNT_NS); | ||||
|             SwitchPreference reauth = (SwitchPreference) findPreference(Const.Key.SU_REAUTH); | ||||
|             SwitchPreference fingerprint = (SwitchPreference) findPreference(Const.Key.SU_FINGERPRINT); | ||||
|  | ||||
|             updateChannel.setOnPreferenceChangeListener((pref, o) -> { | ||||
|                 mm.updateChannel = Integer.parseInt((String) o); | ||||
|                 if (mm.updateChannel == Const.Value.CUSTOM_CHANNEL) { | ||||
|                     View v = LayoutInflater.from(getActivity()).inflate(R.layout.custom_channel_dialog, null); | ||||
|                     EditText url = v.findViewById(R.id.custom_url); | ||||
|                     url.setText(mm.customChannelUrl); | ||||
|                     url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, "")); | ||||
|                     new AlertDialog.Builder(getActivity()) | ||||
|                         .setTitle(R.string.settings_update_custom) | ||||
|                         .setView(v) | ||||
| @@ -144,14 +150,39 @@ public class SettingsActivity extends Activity implements Topic.Subscriber { | ||||
|                 reauth.setSummary(R.string.android_o_not_support); | ||||
|             } | ||||
|  | ||||
|             if (mm.getPackageName().equals(Const.ORIG_PKG_NAME) && mm.magiskVersionCode >= 1440) { | ||||
|                 hideManager.setOnPreferenceClickListener((pref) -> { | ||||
|                     Utils.runWithPermission(getActivity(), | ||||
|                             Manifest.permission.WRITE_EXTERNAL_STORAGE, | ||||
|                             () -> new HideManager(getActivity()).exec()); | ||||
|                     return true; | ||||
|                 }); | ||||
|             // Disable fingerprint option if not possible | ||||
|             if (!FingerprintHelper.canUseFingerprint()) { | ||||
|                 fingerprint.setEnabled(false); | ||||
|                 fingerprint.setSummary(R.string.disable_fingerprint); | ||||
|             } | ||||
|  | ||||
|             if (mm.magiskVersionCode >= 1440) { | ||||
|                 if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) { | ||||
|                     hideManager.setOnPreferenceClickListener((pref) -> { | ||||
|                         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); | ||||
|             } | ||||
|  | ||||
| @@ -216,26 +247,28 @@ public class SettingsActivity extends Activity implements Topic.Subscriber { | ||||
|                     break; | ||||
|                 case Const.Key.COREONLY: | ||||
|                     if (prefs.getBoolean(key, false)) { | ||||
|                         Utils.createFile(Const.MAGISK_DISABLE_FILE); | ||||
|                         try { | ||||
|                             Const.MAGISK_DISABLE_FILE.createNewFile(); | ||||
|                         } catch (IOException ignored) {} | ||||
|                     } else { | ||||
|                         Utils.removeItem(Const.MAGISK_DISABLE_FILE); | ||||
|                         Const.MAGISK_DISABLE_FILE.delete(); | ||||
|                     } | ||||
|                     Toast.makeText(getActivity(), R.string.settings_reboot_toast, Toast.LENGTH_LONG).show(); | ||||
|                     break; | ||||
|                 case Const.Key.MAGISKHIDE: | ||||
|                     if (prefs.getBoolean(key, false)) { | ||||
|                         Shell.su_raw("magiskhide --enable"); | ||||
|                         Shell.Async.su("magiskhide --enable"); | ||||
|                     } else { | ||||
|                         Shell.su_raw("magiskhide --disable"); | ||||
|                         Shell.Async.su("magiskhide --disable"); | ||||
|                     } | ||||
|                     break; | ||||
|                 case Const.Key.HOSTS: | ||||
|                     if (prefs.getBoolean(key, false)) { | ||||
|                         Shell.su_raw( | ||||
|                         Shell.Async.su( | ||||
|                                 "cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(), | ||||
|                                 "mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts"); | ||||
|                     } else { | ||||
|                         Shell.su_raw( | ||||
|                         Shell.Async.su( | ||||
|                                 "umount -l /system/etc/hosts", | ||||
|                                 "rm -f " + Const.MAGISK_HOST_FILE()); | ||||
|                     } | ||||
| @@ -252,6 +285,9 @@ public class SettingsActivity extends Activity implements Topic.Subscriber { | ||||
|                 case Const.Key.UPDATE_CHANNEL: | ||||
|                     new CheckUpdates().exec(); | ||||
|                     break; | ||||
|                 case Const.Key.CHECK_UPDATES: | ||||
|                     mm.setupUpdateCheck(); | ||||
|                     break; | ||||
|             } | ||||
|             mm.loadConfig(); | ||||
|             setSummary(); | ||||
|   | ||||
| @@ -2,10 +2,6 @@ package com.topjohnwu.magisk; | ||||
|  | ||||
| import android.app.NotificationChannel; | ||||
| 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.os.Build; | ||||
| 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.UpdateRepos; | ||||
| import com.topjohnwu.magisk.components.Activity; | ||||
| import com.topjohnwu.magisk.services.UpdateCheckService; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| public class SplashActivity extends Activity { | ||||
|  | ||||
| @@ -50,31 +45,18 @@ public class SplashActivity extends Activity { | ||||
|         LoadModules loadModuleTask = new LoadModules(); | ||||
|  | ||||
|         if (Utils.checkNetworkStatus()) { | ||||
|  | ||||
|             // Fire update check | ||||
|             new CheckUpdates().exec(); | ||||
|  | ||||
|             // Add repo update check | ||||
|             loadModuleTask.setCallBack(() -> new UpdateRepos(false).exec()); | ||||
|         } | ||||
|  | ||||
|         // Magisk working as expected | ||||
|         if (Shell.rootAccess() && mm.magiskVersionCode > 0) { | ||||
|  | ||||
|             // Add update checking service | ||||
|             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); | ||||
|             } | ||||
|  | ||||
|             // Update check service | ||||
|             mm.setupUpdateCheck(); | ||||
|             // Fire asynctasks | ||||
|             loadModuleTask.exec(); | ||||
|  | ||||
|             // Check dtbo status | ||||
|             Utils.patchDTBO(); | ||||
|         } | ||||
|   | ||||
| @@ -18,9 +18,9 @@ import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.asyncs.ParallelTask; | ||||
| import com.topjohnwu.magisk.components.SnackbarMaker; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| @@ -81,10 +81,10 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter. | ||||
|             holder.checkBox.setChecked(mHideList.contains(info.packageName)); | ||||
|             holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> { | ||||
|                 if (isChecked) { | ||||
|                     Shell.su_raw("magiskhide --add " + info.packageName); | ||||
|                     Shell.Async.su("magiskhide --add " + info.packageName); | ||||
|                     mHideList.add(info.packageName); | ||||
|                 } else { | ||||
|                     Shell.su_raw("magiskhide --rm " + info.packageName); | ||||
|                     Shell.Async.su("magiskhide --rm " + 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() | ||||
|                     .compareTo(b.loadLabel(pm).toString().toLowerCase())); | ||||
|             mHideList = Shell.su("magiskhide --ls"); | ||||
|             mHideList = Shell.Sync.su("magiskhide --ls"); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ import android.widget.TextView; | ||||
| import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.components.SnackbarMaker; | ||||
| import com.topjohnwu.magisk.container.Module; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
|   | ||||
| @@ -4,9 +4,9 @@ import android.app.Activity; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| 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.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.BufferedOutputStream; | ||||
| @@ -32,13 +32,13 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> { | ||||
|     } | ||||
|  | ||||
|     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); | ||||
|         dexPath.getParentFile().mkdir(); | ||||
|         try ( | ||||
|                 OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath)); | ||||
|                 InputStream in = new BufferedInputStream(conn.getInputStream())) { | ||||
|             Utils.inToOut(in, out); | ||||
|             ShellUtils.pump(in, out); | ||||
|         } | ||||
|         conn.disconnect(); | ||||
|     } | ||||
|   | ||||
| @@ -33,7 +33,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> { | ||||
|                 jsonStr = WebService.getString(Const.Url.BETA_URL); | ||||
|                 break; | ||||
|             case Const.Value.CUSTOM_CHANNEL: | ||||
|                 jsonStr = WebService.getString(mm.customChannelUrl); | ||||
|                 jsonStr = WebService.getString(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, "")); | ||||
|                 break; | ||||
|         } | ||||
|         try { | ||||
| @@ -54,7 +54,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> { | ||||
|     @Override | ||||
|     protected void onPostExecute(Void v) { | ||||
|         MagiskManager mm = MagiskManager.get(); | ||||
|         if (showNotification && mm.updateNotification) { | ||||
|         if (showNotification) { | ||||
|             if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) { | ||||
|                 ShowUI.managerUpdateNotification(); | ||||
|             } else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) { | ||||
|   | ||||
| @@ -8,9 +8,10 @@ import android.view.View; | ||||
| import com.topjohnwu.magisk.FlashActivity; | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.magisk.utils.ZipUtils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.BufferedOutputStream; | ||||
| @@ -38,8 +39,8 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> { | ||||
|  | ||||
|     private boolean unzipAndCheck() throws Exception { | ||||
|         ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true); | ||||
|         List<String> ret = Utils.readFile(new File(mCachedFile.getParentFile(), "updater-script")); | ||||
|         return Utils.isValidShellResponse(ret) && ret.get(0).contains("#MAGISK"); | ||||
|         String s = Utils.cmd("head -n 1 " + new File(mCachedFile.getParentFile(), "updater-script")); | ||||
|         return s != null && s.contains("#MAGISK"); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -55,7 +56,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> { | ||||
|             ) { | ||||
|                 if (in == null) throw new FileNotFoundException(); | ||||
|                 InputStream buf= new BufferedInputStream(in); | ||||
|                 Utils.inToOut(buf, out); | ||||
|                 ShellUtils.pump(buf, out); | ||||
|             } catch (FileNotFoundException e) { | ||||
|                 console.add("! Invalid Uri"); | ||||
|                 throw e; | ||||
| @@ -65,7 +66,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> { | ||||
|             } | ||||
|             if (!unzipAndCheck()) return 0; | ||||
|             console.add("- Installing " + Utils.getNameFromUri(mm, mUri)); | ||||
|             Shell.getShell().run(console, logs, | ||||
|             Shell.Sync.su(console, logs, | ||||
|                     "cd " + mCachedFile.getParent(), | ||||
|                     "BOOTMODE=true sh update-binary dummy 1 " + mCachedFile + " || echo 'Failed!'" | ||||
|             ); | ||||
| @@ -85,7 +86,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> { | ||||
|     @Override | ||||
|     protected void onPostExecute(Integer result) { | ||||
|         FlashActivity activity = (FlashActivity) getActivity(); | ||||
|         Shell.su_raw( | ||||
|         Shell.Async.su( | ||||
|                 "rm -rf " + mCachedFile.getParent(), | ||||
|                 "rm -rf " + Const.TMP_FOLDER_PATH | ||||
|         ); | ||||
|   | ||||
| @@ -4,18 +4,19 @@ import android.app.Activity; | ||||
| import android.app.ProgressDialog; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import com.topjohnwu.crypto.JarMap; | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| 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.SuFileOutputStream; | ||||
| import com.topjohnwu.utils.JarMap; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.security.SecureRandom; | ||||
| import java.util.List; | ||||
| import java.util.jar.JarEntry; | ||||
|  | ||||
| public class HideManager extends ParallelTask<Void, Void, Boolean> { | ||||
| @@ -104,8 +105,7 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> { | ||||
|         MagiskManager mm = MagiskManager.get(); | ||||
|  | ||||
|         // Generate a new unhide app with random package name | ||||
|         File repack = new File(Const.EXTERNAL_PATH, "repack.apk"); | ||||
|         repack.getParentFile().mkdirs(); | ||||
|         SuFile repack = new SuFile("/data/local/tmp/repack.apk", true); | ||||
|         String pkg = genPackageName("com.", Const.ORIG_PKG_NAME.length()); | ||||
|  | ||||
|         try { | ||||
| @@ -123,19 +123,18 @@ public class HideManager extends ParallelTask<Void, Void, Boolean> { | ||||
|             apk.getOutputStream(je).write(xml); | ||||
|  | ||||
|             // Sign the APK | ||||
|             ZipUtils.signZip(apk, repack, false); | ||||
|             ZipUtils.signZip(apk, new SuFileOutputStream(repack)); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Install the application | ||||
|  | ||||
|         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))) | ||||
|         if (!ShellUtils.fastCmdResult(Shell.getShell(), "pm install " + repack)) | ||||
|             return false; | ||||
|  | ||||
|         repack.delete(); | ||||
|  | ||||
|         mm.suDB.setStrings(Const.Key.SU_REQUESTER, pkg); | ||||
|         Utils.dumpPrefs(); | ||||
|         Utils.uninstallPkg(Const.ORIG_PKG_NAME); | ||||
|   | ||||
| @@ -1,20 +1,22 @@ | ||||
| package com.topjohnwu.magisk.asyncs; | ||||
|  | ||||
| import android.app.Activity; | ||||
| import android.content.res.AssetManager; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.text.TextUtils; | ||||
| import android.view.View; | ||||
|  | ||||
| import com.topjohnwu.crypto.SignBoot; | ||||
| import com.topjohnwu.magisk.FlashActivity; | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.container.TarEntry; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| 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.TarOutputStream; | ||||
| @@ -28,7 +30,6 @@ import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -41,6 +42,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|     private List<String> console, logs; | ||||
|     private String mBootLocation; | ||||
|     private int mode; | ||||
|     private File install; | ||||
|  | ||||
|     private InstallMagisk(Activity context, List<String> console, List<String> logs, Uri zip) { | ||||
|         super(context); | ||||
| @@ -65,12 +67,12 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|     protected Boolean doInBackground(Void... voids) { | ||||
|         MagiskManager mm = MagiskManager.get(); | ||||
|  | ||||
|         File install = new File( | ||||
|         install = new File( | ||||
|                 (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? | ||||
|                         mm.createDeviceProtectedStorageContext() : | ||||
|                         mm).getFilesDir().getParent() | ||||
|                         mm.createDeviceProtectedStorageContext() : mm) | ||||
|                         .getFilesDir().getParent() | ||||
|                 , "install"); | ||||
|         Shell.sh_raw("rm -rf " + install); | ||||
|         Shell.Sync.sh("rm -rf " + install); | ||||
|  | ||||
|         List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS); | ||||
|         String arch; | ||||
| @@ -102,17 +104,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|                 console.add("! Cannot unzip zip"); | ||||
|                 throw e; | ||||
|             } | ||||
|             Shell.sh("chmod 755 " + install + "/*"); | ||||
|             Shell.Sync.sh("chmod 755 " + install + "/*"); | ||||
|  | ||||
|             File boot = new File(install, "boot.img"); | ||||
|             boolean highCompression = false; | ||||
|             switch (mode) { | ||||
|                 case PATCH_MODE: | ||||
|                     console.add("- Use boot image: " + boot); | ||||
|                     // Copy boot image to local | ||||
|                     try ( | ||||
|                         InputStream in = mm.getContentResolver().openInputStream(mBootImg); | ||||
|                         OutputStream out = new FileOutputStream(boot) | ||||
|                     try (InputStream in = mm.getContentResolver().openInputStream(mBootImg); | ||||
|                          OutputStream out = new FileOutputStream(boot) | ||||
|                     ) { | ||||
|                         InputStream source; | ||||
|                         if (in == null) throw new FileNotFoundException(); | ||||
| @@ -130,7 +130,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|                             // Direct copy raw image | ||||
|                             source = new BufferedInputStream(in); | ||||
|                         } | ||||
|                         Utils.inToOut(source, out); | ||||
|                         ShellUtils.pump(source, out); | ||||
|                     } catch (FileNotFoundException e) { | ||||
|                         console.add("! Invalid Uri"); | ||||
|                         throw e; | ||||
| @@ -140,21 +140,16 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|                     } | ||||
|                     break; | ||||
|                 case DIRECT_MODE: | ||||
|                     console.add("- Use boot image: " + mBootLocation); | ||||
|                     console.add("- Patch boot/ramdisk image: " + mBootLocation); | ||||
|                     if (mm.remoteMagiskVersionCode >= 1463) { | ||||
|                         List<String> ret = new ArrayList<>(); | ||||
|                          Shell.getShell().run(ret, logs, | ||||
|                                 install + "/magiskboot --parse " + mBootLocation, | ||||
|                                 "echo $?" | ||||
|                         ); | ||||
|                         if (Utils.isValidShellResponse(ret)) { | ||||
|                             highCompression = Integer.parseInt(ret.get(ret.size() - 1)) == 2; | ||||
|                             if (highCompression) | ||||
|                                 console.add("! Insufficient boot partition size detected"); | ||||
|                         } | ||||
|                         highCompression = Integer.parseInt(Utils.cmd(Utils.fmt( | ||||
|                                 "%s/magiskboot --parse %s; echo $?", | ||||
|                                 install, mBootLocation))) == 2; | ||||
|                         if (highCompression) | ||||
|                             console.add("! Insufficient boot partition size detected"); | ||||
|                     } | ||||
|                     if (boot.createNewFile()) { | ||||
|                         Shell.su("cat " + mBootLocation + " > " + boot); | ||||
|                         Shell.Sync.su("cat " + mBootLocation + " > " + boot); | ||||
|                     } else { | ||||
|                         console.add("! Dump boot image failed"); | ||||
|                         return false; | ||||
| @@ -168,22 +163,15 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|             try (InputStream in = new FileInputStream(boot)) { | ||||
|                 isSigned = SignBoot.verifySignature(in, null); | ||||
|                 if (isSigned) { | ||||
|                     console.add("- Signed boot image detected"); | ||||
|                     console.add("- Boot image is signed with AVB 1.0"); | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 console.add("! Unable to check signature"); | ||||
|                 throw e; | ||||
|             } | ||||
|  | ||||
|             // Force non-root shell | ||||
|             Shell shell; | ||||
|             if (Shell.rootAccess()) | ||||
|                 shell = new Shell("sh"); | ||||
|             else | ||||
|                 shell = Shell.getShell(); | ||||
|  | ||||
|             // Patch boot image | ||||
|             shell.run(console, logs, | ||||
|             Shell.Sync.sh(console, logs, | ||||
|                     "cd " + install, | ||||
|                     Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " + | ||||
|                                     "sh update-binary indep boot_patch.sh %s || echo 'Failed!'", | ||||
| @@ -192,27 +180,22 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|             if (TextUtils.equals(console.get(console.size() - 1), "Failed!")) | ||||
|                 return false; | ||||
|  | ||||
|             shell.run(null, null, | ||||
|                     "mv -f new-boot.img ../", | ||||
|             Shell.Sync.sh("mv -f new-boot.img ../", | ||||
|                     "mv bin/busybox busybox", | ||||
|                     "rm -rf bin *.img update-binary", | ||||
|                     "cd /"); | ||||
|  | ||||
|             File patched_boot = new File(install.getParent(), "new-boot.img"); | ||||
|             SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img"); | ||||
|  | ||||
|             if (isSigned) { | ||||
|                 console.add("- Signing boot image"); | ||||
|                 console.add("- Signing boot image with test keys"); | ||||
|                 File signed = new File(install.getParent(), "signed.img"); | ||||
|                 AssetManager assets = mm.getAssets(); | ||||
|                 try ( | ||||
|                         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) | ||||
|                 try (InputStream in = new SuFileInputStream(patched_boot); | ||||
|                      OutputStream out = new BufferedOutputStream(new FileOutputStream(signed)) | ||||
|                 ) { | ||||
|                     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) { | ||||
| @@ -230,8 +213,8 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|                             out = new BufferedOutputStream(new FileOutputStream(dest)); | ||||
|                             break; | ||||
|                     } | ||||
|                     try (InputStream in = new BufferedInputStream(new FileInputStream(patched_boot))) { | ||||
|                         Utils.inToOut(in, out); | ||||
|                     try (InputStream in = new SuFileInputStream(patched_boot)) { | ||||
|                         ShellUtils.pump(in, out); | ||||
|                         out.close(); | ||||
|                     } | ||||
|                     console.add(""); | ||||
| @@ -242,7 +225,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|                     break; | ||||
|                 case DIRECT_MODE: | ||||
|                     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("cp -af %s/* %s; rm -rf %s", install, binPath, install), | ||||
|                             Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation), | ||||
| @@ -267,6 +250,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { | ||||
|     protected void onPostExecute(Boolean result) { | ||||
|         FlashActivity activity = (FlashActivity) getActivity(); | ||||
|         if (!result) { | ||||
|             Shell.Async.sh("rm -rf " + install); | ||||
|             console.add("! Installation failed"); | ||||
|             activity.reboot.setVisibility(View.GONE); | ||||
|         } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.container.Module; | ||||
| import com.topjohnwu.magisk.container.ValueSortedMap; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| @@ -12,7 +12,7 @@ public class LoadModules extends ParallelTask<Void, Void, Void> { | ||||
|  | ||||
|     private List<String> getModList() { | ||||
|         String command = "ls -d " + Const.MAGISK_PATH() + "/* | grep -v lost+found"; | ||||
|         return Shell.su(command); | ||||
|         return Shell.Sync.su(command); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -6,8 +6,8 @@ import android.webkit.WebView; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.magisk.utils.WebService; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import org.commonmark.node.Node; | ||||
| import org.commonmark.parser.Parser; | ||||
| @@ -44,7 +44,7 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> { | ||||
|             md = WebService.getString(mUrl); | ||||
|         } else { | ||||
|             try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { | ||||
|                 Utils.inToOut(is, out); | ||||
|                 ShellUtils.pump(is, out); | ||||
|                 md = out.toString(); | ||||
|                 is.close(); | ||||
|             } catch (IOException e) { | ||||
| @@ -54,11 +54,13 @@ public class MarkDownWindow extends ParallelTask<Void, Void, String> { | ||||
|         } | ||||
|         String css; | ||||
|         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() | ||||
|         ) { | ||||
|             Utils.inToOut(in, out); | ||||
|             ShellUtils.pump(in, out); | ||||
|             css = out.toString(); | ||||
|             in.close(); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|             return ""; | ||||
|   | ||||
| @@ -13,10 +13,11 @@ import com.topjohnwu.magisk.FlashActivity; | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.R; | ||||
| 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.ZipUtils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.BufferedOutputStream; | ||||
| @@ -68,7 +69,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> { | ||||
|                     continue; | ||||
|                 } | ||||
|                 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())); | ||||
|                 OutputStream out = new BufferedOutputStream(new FileOutputStream(temp1)) | ||||
|             ) { | ||||
|                 Utils.inToOut(in, out); | ||||
|                 ShellUtils.pump(in, out); | ||||
|                 in.close(); | ||||
|             } | ||||
|             conn.disconnect(); | ||||
| @@ -120,14 +121,8 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> { | ||||
|             // First remove top folder in Github source zip, temp1 -> temp2 | ||||
|             removeTopFolder(temp1, temp2); | ||||
|  | ||||
|             // Then sign the zip for the first time, temp2 -> temp1 | ||||
|             ZipUtils.signZip(temp2, temp1, false); | ||||
|  | ||||
|             // 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); | ||||
|             // Then sign the zip | ||||
|             ZipUtils.signZip(temp2, mFile); | ||||
|  | ||||
|             // Delete temp files | ||||
|             temp1.delete(); | ||||
|   | ||||
| @@ -4,29 +4,24 @@ import android.widget.Toast; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
|  | ||||
| import java.util.List; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| public class RestoreImages extends ParallelTask<Void, Void, Boolean> { | ||||
|  | ||||
|     @Override | ||||
|     protected Boolean doInBackground(Void... voids) { | ||||
|         String sha1; | ||||
|         List<String> ret = Utils.readFile("/.backup/.sha1"); | ||||
|         if (Utils.isValidShellResponse(ret)) { | ||||
|             sha1 = ret.get(0); | ||||
|         } else { | ||||
|             ret = Shell.su("cat /init.magisk.rc | grep STOCKSHA1"); | ||||
|             if (!Utils.isValidShellResponse(ret)) | ||||
|         sha1 = Utils.cmd("cat /.backup/.sha1"); | ||||
|         if (sha1 == null) { | ||||
|             sha1 = Utils.cmd("cat /init.magisk.rc | grep STOCKSHA1"); | ||||
|             if (sha1 == null) | ||||
|                 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 Utils.isValidShellResponse(ret) && Boolean.parseBoolean(ret.get(ret.size() - 1)); | ||||
|         return ShellUtils.fastCmdResult(Shell.getShell(), "restore_imgs " + sha1); | ||||
|     } | ||||
|  | ||||
|     @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; | ||||
|  | ||||
| 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 { | ||||
|  | ||||
|     private String mRemoveFile, mDisableFile, mUpdateFile; | ||||
|     private SuFile mRemoveFile, mDisableFile, mUpdateFile; | ||||
|     private boolean mEnable, mRemove, mUpdated; | ||||
|  | ||||
|     public Module(String path) { | ||||
|  | ||||
|         try { | ||||
|             parseProps(Utils.readFile(path + "/module.prop")); | ||||
|             parseProps(Shell.Sync.su("cat " + path + "/module.prop")); | ||||
|         } catch (NumberFormatException ignored) {} | ||||
|  | ||||
|         mRemoveFile = path + "/remove"; | ||||
|         mDisableFile = path + "/disable"; | ||||
|         mUpdateFile = path + "/update"; | ||||
|         mRemoveFile = new SuFile(path + "/remove", true); | ||||
|         mDisableFile = new SuFile(path + "/disable", true); | ||||
|         mUpdateFile = new SuFile(path + "/update", true); | ||||
|  | ||||
|         if (getId() == null) { | ||||
|             int sep = path.lastIndexOf('/'); | ||||
| @@ -26,19 +29,21 @@ public class Module extends BaseModule { | ||||
|             setName(getId()); | ||||
|         } | ||||
|  | ||||
|         mEnable = !Utils.itemExist(mDisableFile); | ||||
|         mRemove = Utils.itemExist(mRemoveFile); | ||||
|         mUpdated = Utils.itemExist(mUpdateFile); | ||||
|         mEnable = !mDisableFile.exists(); | ||||
|         mRemove = mRemoveFile.exists(); | ||||
|         mUpdated = mUpdateFile.exists(); | ||||
|     } | ||||
|  | ||||
|     public void createDisableFile() { | ||||
|         mEnable = false; | ||||
|         Utils.createFile(mDisableFile); | ||||
|         try { | ||||
|             mDisableFile.createNewFile(); | ||||
|         } catch (IOException ignored) {} | ||||
|     } | ||||
|  | ||||
|     public void removeDisableFile() { | ||||
|         mEnable = true; | ||||
|         Utils.removeItem(mDisableFile); | ||||
|         mDisableFile.delete(); | ||||
|     } | ||||
|  | ||||
|     public boolean isEnabled() { | ||||
| @@ -47,12 +52,14 @@ public class Module extends BaseModule { | ||||
|  | ||||
|     public void createRemoveFile() { | ||||
|         mRemove = true; | ||||
|         Utils.createFile(mRemoveFile); | ||||
|         try { | ||||
|             mRemoveFile.createNewFile(); | ||||
|         } catch (IOException ignored) {} | ||||
|     } | ||||
|  | ||||
|     public void deleteRemoveFile() { | ||||
|         mRemove = false; | ||||
|         Utils.removeItem(mRemoveFile); | ||||
|         mRemoveFile.delete(); | ||||
|     } | ||||
|  | ||||
|     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), | ||||
|                 Utils.fmt("MagiskManager-v%s.apk", intent.getStringExtra(Const.Key.INTENT_SET_VERSION)) | ||||
|                 intent.getStringExtra(Const.Key.INTENT_SET_FILENAME) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,8 +5,9 @@ import android.content.Context; | ||||
| import android.content.Intent; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| public class PackageReceiver extends BroadcastReceiver { | ||||
|     @Override | ||||
| @@ -18,13 +19,13 @@ public class PackageReceiver extends BroadcastReceiver { | ||||
|         switch (intent.getAction()) { | ||||
|             case Intent.ACTION_PACKAGE_REPLACED: | ||||
|                 // This will only work pre-O | ||||
|                 if (mm.suReauth) { | ||||
|                 if (mm.prefs.getBoolean(Const.Key.SU_REAUTH, false)) { | ||||
|                     mm.suDB.deletePolicy(pkg); | ||||
|                 } | ||||
|                 break; | ||||
|             case Intent.ACTION_PACKAGE_FULLY_REMOVED: | ||||
|                 mm.suDB.deletePolicy(pkg); | ||||
|                 Shell.su_raw("magiskhide --rm " + pkg); | ||||
|                 Shell.Async.su("magiskhide --rm " + pkg); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -4,11 +4,11 @@ import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
|  | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| public class RebootReceiver extends BroadcastReceiver { | ||||
|     @Override | ||||
|     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.R; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Shell; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| public class OnBootIntentService extends IntentService { | ||||
|  | ||||
| @@ -41,6 +41,7 @@ public class OnBootIntentService extends IntentService { | ||||
|          * */ | ||||
|         MagiskManager mm = Utils.getMagiskManager(this); | ||||
|         mm.loadMagiskInfo(); | ||||
|         mm.getDefaultInstallFlags(); | ||||
|         if (Shell.rootAccess()) { | ||||
|             Utils.patchDTBO(); | ||||
|         } | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user