mirror of
				https://github.com/topjohnwu/Magisk
				synced 2025-10-30 09:00:52 +01:00 
			
		
		
		
	Compare commits
	
		
			164 Commits
		
	
	
		
			manager-v5
			...
			manager-v5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | b885ccbd63 | ||
|   | da6f1d0f12 | ||
|   | 4c0d435b6b | ||
|   | 0e717a2de4 | ||
|   | cada862214 | ||
|   | 682c6d4e7b | ||
|   | d0a253c97e | ||
|   | c0e2b3027b | ||
|   | e7dc14b07d | ||
|   | 0da9146e90 | ||
|   | ad05a33e02 | ||
|   | 8224e038a3 | ||
|   | 03c04c2141 | ||
|   | 2e091b04e5 | ||
|   | 60296493fe | ||
|   | 20c20f8f9b | ||
|   | f1d642a4e5 | ||
|   | e0e5ea17a4 | ||
|   | 91a0ba72dc | ||
|   | c54c5a974a | ||
|   | 532b8c54ab | ||
|   | 5ac87891b5 | ||
|   | 2d905ce3fb | ||
|   | 831112abd2 | ||
|   | 153d0f5505 | ||
|   | c78896a335 | ||
|   | 316ec98e0f | ||
|   | cf58545a45 | ||
|   | e86015badc | ||
|   | c8f65fc9a1 | ||
|   | 7684602ea8 | ||
|   | 4601989d4a | ||
|   | 23f697d62b | ||
|   | 4ff39f8817 | ||
|   | 1df41003ec | ||
|   | 1f39ee41ad | ||
|   | 42d8b1ecb9 | ||
|   | a4da7b33e6 | ||
|   | e4ee9e9095 | ||
|   | 77430a282f | ||
|   | e6c1dd532d | ||
|   | d1f301e059 | ||
|   | 1e812c40ce | ||
|   | a949641342 | ||
|   | c231e88a5d | ||
|   | 79c71509f6 | ||
|   | 5dab580cfc | ||
|   | 499a157946 | ||
|   | c5a7ab2415 | ||
|   | 3dd5a6f378 | ||
|   | 7be26a0677 | ||
|   | c183fdd3ca | ||
|   | baa439457e | ||
|   | 4dbcd54b72 | ||
|   | 11062f2d4f | ||
|   | a0466085fe | ||
|   | f2f7d77847 | ||
|   | b2105f2d88 | ||
|   | 4126f3bdcb | ||
|   | 74ccfe6088 | ||
|   | 48085b5573 | ||
|   | 7b9ddc9b3b | ||
|   | 15726a759c | ||
|   | 2c7474ea87 | ||
|   | c726aee643 | ||
|   | c3e94e1480 | ||
|   | 5f1343e5b4 | ||
|   | ffb1303d61 | ||
|   | a0b0d938f0 | ||
|   | 158f5ba7d9 | ||
|   | b8cf40161c | ||
|   | fb96e6a56f | ||
|   | 6668ba2511 | ||
|   | 4668ef3020 | ||
|   | 630f2b7d19 | ||
|   | dde0a4a7c8 | ||
|   | b06f69573d | ||
|   | 8fd03f7434 | ||
|   | 90e4ac2d23 | ||
|   | 956bceae75 | ||
|   | c663be86de | ||
|   | aca78baecf | ||
|   | fbcf6b7954 | ||
|   | 84123222aa | ||
|   | e9dbcf693d | ||
|   | 1cd0a9d48f | ||
|   | 1b48e44914 | ||
|   | 0a398f03fd | ||
|   | 15ed3e52f2 | ||
|   | 8990919dab | ||
|   | e5638e4b15 | ||
|   | 404c6fac9a | ||
|   | 267395bfa2 | ||
|   | 920fc5ae99 | ||
|   | 92ed0ae51b | ||
|   | 6764a98409 | ||
|   | fd7b5f393a | ||
|   | 2ca528f93f | ||
|   | ce2e6b7d35 | ||
|   | 684c5d225a | ||
|   | b75018b03b | ||
|   | 41499d4b3c | ||
|   | 383c97c303 | ||
|   | 74b54ef371 | ||
|   | bbf7b4db79 | ||
|   | c61f0acab5 | ||
|   | 398af123b2 | ||
|   | 315fa9d7d3 | ||
|   | fb5e8ef40c | ||
|   | e79d764148 | ||
|   | ebbee0dc43 | ||
|   | ed0c16e201 | ||
|   | 209fdf349a | ||
|   | f49f2afacd | ||
|   | 8c6330a3c4 | ||
|   | 337b777125 | ||
|   | 1b756e8d96 | ||
|   | 52d478df1a | ||
|   | 0c782edf21 | ||
|   | e3948d295e | ||
|   | 5f2c742a5c | ||
|   | b30c77aab9 | ||
|   | a5916b9c49 | ||
|   | 453180e30b | ||
|   | 8bd432d391 | ||
|   | c9d3e20aef | ||
|   | 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 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,7 +6,7 @@ | ||||
| app/release | ||||
| *.hprof | ||||
| .externalNativeBuild/ | ||||
| *.sh | ||||
| src/full/res/raw/util_functions.sh | ||||
| public.certificate.x509.pem | ||||
| private.key.pk8 | ||||
| *.apk | ||||
|   | ||||
| @@ -1,2 +1,7 @@ | ||||
| # Magisk Manager | ||||
| This repo is no longer an independent component. It is a submodule of the [Magisk Project](https://github.com/topjohnwu/Magisk). | ||||
|  | ||||
| # Translations | ||||
| The default (English) string resources are scattered in these files: `src/full/res/values/strings.xml`, `src/main/res/values/strings.xml`, `src/stub/res/values/strings.xml`.   | ||||
| Place the translated XMLs in the corresponding folder to the locale.   | ||||
| Translations are highly appreciated via pull requests here on Github. | ||||
|   | ||||
							
								
								
									
										50
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								build.gradle
									
									
									
									
									
								
							| @@ -1,15 +1,13 @@ | ||||
| apply plugin: 'com.android.application' | ||||
|  | ||||
| android { | ||||
|     compileSdkVersion 27 | ||||
|     buildToolsVersion "27.0.3" | ||||
|     compileSdkVersion rootProject.ext.compileSdkVersion | ||||
|     buildToolsVersion rootProject.ext.buildToolsVersion | ||||
|  | ||||
|     defaultConfig { | ||||
|         applicationId "com.topjohnwu.magisk" | ||||
|         minSdkVersion 21 | ||||
|         targetSdkVersion 27 | ||||
|         versionCode 100 | ||||
|         versionName "5.6.0" | ||||
|         targetSdkVersion rootProject.ext.compileSdkVersion | ||||
|         javaCompileOptions { | ||||
|             annotationProcessorOptions { | ||||
|                 argument('butterknife.debuggable', 'false') | ||||
| @@ -21,9 +19,23 @@ android { | ||||
|         release { | ||||
|             minifyEnabled true | ||||
|             shrinkResources true | ||||
|             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | ||||
|             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     flavorDimensions "mode" | ||||
|  | ||||
|     productFlavors { | ||||
|         full { | ||||
|             versionCode 125 | ||||
|             versionName "5.8.0" | ||||
|         } | ||||
|         stub { | ||||
|             versionCode 1 | ||||
|             versionName "stub" | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     compileOptions { | ||||
|         sourceCompatibility JavaVersion.VERSION_1_8 | ||||
|         targetCompatibility JavaVersion.VERSION_1_8 | ||||
| @@ -37,23 +49,17 @@ android { | ||||
|     } | ||||
| } | ||||
|  | ||||
| repositories { | ||||
|     jcenter() | ||||
|     google() | ||||
|     maven { url "https://jitpack.io" } | ||||
| } | ||||
|  | ||||
| dependencies { | ||||
|     implementation fileTree(include: ['*.jar'], dir: 'libs') | ||||
|     implementation project(':utils') | ||||
|     implementation 'com.github.topjohnwu:libsu:1.1.0' | ||||
|     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' | ||||
|     implementation 'com.android.support:support-v4:27.0.2' | ||||
|     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' | ||||
|     fullImplementation project(':utils') | ||||
|     implementation "com.android.support:support-core-utils:${rootProject.ext.supportLibVersion}" | ||||
|     fullImplementation "com.android.support:preference-v7:${rootProject.ext.supportLibVersion}" | ||||
|     fullImplementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}" | ||||
|     fullImplementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}" | ||||
|     fullImplementation "com.android.support:design:${rootProject.ext.supportLibVersion}" | ||||
|     fullImplementation 'com.github.topjohnwu:libsu:1.2.0' | ||||
|     fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0' | ||||
|     fullImplementation 'org.kamranzafar:jtar:2.3' | ||||
|     fullImplementation 'com.jakewharton:butterknife:8.8.1' | ||||
|     annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' | ||||
| } | ||||
|   | ||||
							
								
								
									
										82
									
								
								src/full/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/full/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="com.topjohnwu.magisk"> | ||||
|  | ||||
|     <uses-permission android:name="android.permission.VIBRATE" /> | ||||
|     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> | ||||
|     <uses-permission android:name="android.permission.USE_FINGERPRINT" /> | ||||
|  | ||||
|     <application | ||||
|         android:name=".MagiskManager" | ||||
|         android:theme="@style/AppTheme"> | ||||
|  | ||||
|         <activity | ||||
|             android:name=".MainActivity" | ||||
|             android:configChanges="orientation|screenSize" | ||||
|             android:exported="true" /> | ||||
|         <activity | ||||
|             android:name=".SplashActivity" | ||||
|             android:configChanges="orientation|screenSize" | ||||
|             android:exported="true" | ||||
|             android:theme="@style/SplashTheme"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|         <activity | ||||
|             android:name=".AboutActivity" | ||||
|             android:theme="@style/AppTheme.StatusBar" /> | ||||
|         <activity | ||||
|             android:name=".SettingsActivity" | ||||
|             android:theme="@style/AppTheme.StatusBar" /> | ||||
|         <activity | ||||
|             android:name=".FlashActivity" | ||||
|             android:configChanges="keyboardHidden|orientation|screenSize" | ||||
|             android:screenOrientation="nosensor" | ||||
|             android:theme="@style/AppTheme.StatusBar" /> | ||||
|         <activity | ||||
|             android:name=".NoUIActivity" | ||||
|             android:theme="@style/AppTheme.Translucent" /> | ||||
|         <activity | ||||
|             android:name=".superuser.RequestActivity" | ||||
|             android:excludeFromRecents="true" | ||||
|             android:launchMode="singleTask" | ||||
|             android:taskAffinity="internal.superuser" | ||||
|             android:theme="@style/SuRequest" /> | ||||
|  | ||||
|         <receiver android:name=".superuser.SuReceiver" /> | ||||
|         <receiver android:name=".receivers.BootReceiver"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.BOOT_COMPLETED" /> | ||||
|             </intent-filter> | ||||
|         </receiver> | ||||
|         <receiver android:name=".receivers.PackageReceiver"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.PACKAGE_REPLACED" /> | ||||
|                 <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" /> | ||||
|                 <data android:scheme="package" /> | ||||
|             </intent-filter> | ||||
|         </receiver> | ||||
|         <receiver android:name=".receivers.ManagerUpdate" /> | ||||
|         <receiver android:name=".receivers.RebootReceiver" /> | ||||
|         <receiver android:name=".receivers.ShortcutReceiver"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.LOCALE_CHANGED" /> | ||||
|             </intent-filter> | ||||
|         </receiver> | ||||
|  | ||||
|         <service android:name=".services.OnBootIntentService" /> | ||||
|         <service | ||||
|             android:name=".services.UpdateCheckService" | ||||
|             android:exported="true" | ||||
|             android:permission="android.permission.BIND_JOB_SERVICE" /> | ||||
|  | ||||
|         <!-- Hardcode GMS version --> | ||||
|         <meta-data | ||||
|             android:name="com.google.android.gms.version" | ||||
|             android:value="7095000" /> | ||||
|  | ||||
|     </application> | ||||
|  | ||||
| </manifest> | ||||
| @@ -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; | ||||
| @@ -33,7 +31,7 @@ public class AboutActivity extends Activity { | ||||
|  | ||||
|     @Override | ||||
|     public int getDarkTheme() { | ||||
|         return R.style.AppTheme_Transparent_Dark; | ||||
|         return R.style.AppTheme_StatusBar_Dark; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -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); | ||||
| @@ -3,6 +3,7 @@ package com.topjohnwu.magisk; | ||||
| import android.content.Intent; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.support.v7.app.ActionBar; | ||||
| import android.support.v7.widget.Toolbar; | ||||
| import android.text.TextUtils; | ||||
| @@ -17,6 +18,7 @@ import com.topjohnwu.magisk.asyncs.FlashZip; | ||||
| import com.topjohnwu.magisk.asyncs.InstallMagisk; | ||||
| import com.topjohnwu.magisk.components.Activity; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.RootUtils; | ||||
| import com.topjohnwu.superuser.CallbackList; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| @@ -77,7 +79,7 @@ public class FlashActivity extends Activity { | ||||
|  | ||||
|     @Override | ||||
|     public int getDarkTheme() { | ||||
|         return R.style.AppTheme_Transparent_Dark; | ||||
|         return R.style.AppTheme_StatusBar_Dark; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -113,13 +115,18 @@ public class FlashActivity extends Activity { | ||||
|             case Const.Value.FLASH_ZIP: | ||||
|                 new FlashZip(this, uri, console, logs).exec(); | ||||
|                 break; | ||||
|             case Const.Value.PATCH_BOOT: | ||||
|                 new InstallMagisk(this, console, logs, uri, (Uri) intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)) | ||||
|                         .exec(); | ||||
|             case Const.Value.UNINSTALL: | ||||
|                 new UninstallMagisk(this, uri, console, logs).exec(); | ||||
|                 break; | ||||
|             case Const.Value.FLASH_MAGISK: | ||||
|                 new InstallMagisk(this, console, logs, uri, intent.getStringExtra(Const.Key.FLASH_SET_BOOT)) | ||||
|                         .exec(); | ||||
|                 new InstallMagisk(this, console, logs, uri, InstallMagisk.DIRECT_MODE).exec(); | ||||
|                 break; | ||||
|             case Const.Value.FLASH_SECOND_SLOT: | ||||
|                 new InstallMagisk(this, console, logs, uri, InstallMagisk.SECOND_SLOT_MODE).exec(); | ||||
|                 break; | ||||
|             case Const.Value.PATCH_BOOT: | ||||
|                 new InstallMagisk(this, console, logs, uri, | ||||
|                         intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec(); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| @@ -128,4 +135,21 @@ public class FlashActivity extends Activity { | ||||
|     public void onBackPressed() { | ||||
|         // Prevent user accidentally press back button | ||||
|     } | ||||
|  | ||||
|     private static class UninstallMagisk extends FlashZip { | ||||
|  | ||||
|         private UninstallMagisk(Activity context, Uri uri, List<String> console, List<String> logs) { | ||||
|             super(context, uri, console, logs); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected void onPostExecute(Integer result) { | ||||
|             if (result == 1) { | ||||
|                 new Handler().postDelayed(() -> | ||||
|                         RootUtils.uninstallPkg(getActivity().getPackageName()), 3000); | ||||
|             } else { | ||||
|                 super.onPostExecute(result); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -7,6 +7,7 @@ import android.support.annotation.Nullable; | ||||
| import android.support.annotation.StringRes; | ||||
| import android.support.v4.widget.SwipeRefreshLayout; | ||||
| import android.support.v7.widget.CardView; | ||||
| import android.text.TextUtils; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| @@ -22,10 +23,13 @@ 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.Const; | ||||
| import com.topjohnwu.magisk.utils.ISafetyNetHelper; | ||||
| import com.topjohnwu.magisk.utils.ShowUI; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import butterknife.BindColor; | ||||
| import butterknife.BindView; | ||||
| @@ -36,14 +40,6 @@ import butterknife.Unbinder; | ||||
| public class MagiskFragment extends Fragment | ||||
|         implements Topic.Subscriber, SwipeRefreshLayout.OnRefreshListener, ExpandableView { | ||||
|  | ||||
|     private static final int CAUSE_SERVICE_DISCONNECTED = 0x01; | ||||
|     private static final int CAUSE_NETWORK_LOST = 0x02; | ||||
|     private static final int RESPONSE_ERR = 0x04; | ||||
|     private static final int CONNECTION_FAIL = 0x08; | ||||
|  | ||||
|     private static final int BASIC_PASS = 0x10; | ||||
|     private static final int CTS_PASS = 0x20; | ||||
|  | ||||
|     private Container expandableContainer = new Container(); | ||||
|  | ||||
|     private MagiskManager mm; | ||||
| @@ -91,7 +87,14 @@ public class MagiskFragment extends Fragment | ||||
|             new CheckSafetyNet(getActivity()).exec(); | ||||
|             collapse(); | ||||
|         }; | ||||
|         if (!CheckSafetyNet.dexPath.exists()) { | ||||
|         if (!TextUtils.equals(mm.getPackageName(), Const.ORIG_PKG_NAME)) { | ||||
|             new AlertDialogBuilder(getActivity()) | ||||
|                     .setTitle(R.string.cannot_check_sn_title) | ||||
|                     .setMessage(R.string.cannot_check_sn_notice) | ||||
|                     .setCancelable(true) | ||||
|                     .setPositiveButton(R.string.ok, null) | ||||
|                     .show(); | ||||
|         } else if (!CheckSafetyNet.dexPath.exists()) { | ||||
|             // Show dialog | ||||
|             new AlertDialogBuilder(getActivity()) | ||||
|                     .setTitle(R.string.proprietary_title) | ||||
| @@ -159,8 +162,8 @@ public class MagiskFragment extends Fragment | ||||
|  | ||||
|         safetyNetStatusText.setText(R.string.safetyNet_check_text); | ||||
|  | ||||
|         mm.safetyNetDone.hasPublished = false; | ||||
|         mm.updateCheckDone.hasPublished = false; | ||||
|         mm.safetyNetDone.reset(); | ||||
|         mm.updateCheckDone.reset(); | ||||
|         mm.remoteMagiskVersionString = null; | ||||
|         mm.remoteMagiskVersionCode = -1; | ||||
|         collapse(); | ||||
| @@ -176,11 +179,11 @@ public class MagiskFragment extends Fragment | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onTopicPublished(Topic topic, Object result) { | ||||
|     public void onTopicPublished(Topic topic) { | ||||
|         if (topic == mm.updateCheckDone) { | ||||
|             updateCheckUI(); | ||||
|         } else if (topic == mm.safetyNetDone) { | ||||
|             updateSafetyNetUI((int) result); | ||||
|             updateSafetyNetUI((int) topic.getResults()[0]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -205,7 +208,7 @@ public class MagiskFragment extends Fragment | ||||
|  | ||||
|         boolean hasNetwork = Utils.checkNetworkStatus(); | ||||
|         boolean hasRoot = Shell.rootAccess(); | ||||
|         boolean isUpToDate = mm.magiskVersionCode > 1300; | ||||
|         boolean isUpToDate = mm.magiskVersionCode > Const.MAGISK_VER.UNIFIED; | ||||
|  | ||||
|         magiskUpdate.setVisibility(hasNetwork ? View.VISIBLE : View.GONE); | ||||
|         safetyNetCard.setVisibility(hasNetwork ? View.VISIBLE : View.GONE); | ||||
| @@ -250,17 +253,22 @@ public class MagiskFragment extends Fragment | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!shownDialog && (mm.remoteMagiskVersionCode > mm.magiskVersionCode | ||||
|                 || mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE)) { | ||||
|                 install(); | ||||
|         } | ||||
|  | ||||
|         magiskUpdateIcon.setImageResource(image); | ||||
|         magiskUpdateIcon.setColorFilter(color); | ||||
|         magiskUpdateIcon.setVisibility(View.VISIBLE); | ||||
|  | ||||
|         magiskUpdateProgress.setVisibility(View.GONE); | ||||
|         mSwipeRefreshLayout.setRefreshing(false); | ||||
|  | ||||
|         if (!shownDialog) { | ||||
|             if (mm.remoteMagiskVersionCode > mm.magiskVersionCode | ||||
|                     || mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE) { | ||||
|                 install(); | ||||
|             } else if (mm.remoteMagiskVersionCode >= Const.MAGISK_VER.FIX_ENV && | ||||
|                     !ShellUtils.fastCmdResult("env_check")) { | ||||
|                 ShowUI.envFixDialog(getActivity()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void updateSafetyNetUI(int response) { | ||||
| @@ -270,12 +278,12 @@ public class MagiskFragment extends Fragment | ||||
|             safetyNetStatusText.setText(R.string.safetyNet_check_success); | ||||
|  | ||||
|             boolean b; | ||||
|             b = (response & CTS_PASS) != 0; | ||||
|             b = (response & ISafetyNetHelper.CTS_PASS) != 0; | ||||
|             ctsStatusText.setText("ctsProfile: " + b); | ||||
|             ctsStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel); | ||||
|             ctsStatusIcon.setColorFilter(b ? colorOK : colorBad); | ||||
|  | ||||
|             b = (response & BASIC_PASS) != 0; | ||||
|             b = (response & ISafetyNetHelper.BASIC_PASS) != 0; | ||||
|             basicStatusText.setText("basicIntegrity: " + b); | ||||
|             basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel); | ||||
|             basicStatusIcon.setColorFilter(b ? colorOK : colorBad); | ||||
| @@ -284,16 +292,16 @@ public class MagiskFragment extends Fragment | ||||
|         } else { | ||||
|             @StringRes int resid; | ||||
|             switch (response) { | ||||
|                 case CAUSE_SERVICE_DISCONNECTED: | ||||
|                 case ISafetyNetHelper.CAUSE_SERVICE_DISCONNECTED: | ||||
|                     resid = R.string.safetyNet_network_loss; | ||||
|                     break; | ||||
|                 case CAUSE_NETWORK_LOST: | ||||
|                 case ISafetyNetHelper.CAUSE_NETWORK_LOST: | ||||
|                     resid = R.string.safetyNet_service_disconnected; | ||||
|                     break; | ||||
|                 case RESPONSE_ERR: | ||||
|                 case ISafetyNetHelper.RESPONSE_ERR: | ||||
|                     resid = R.string.safetyNet_res_invalid; | ||||
|                     break; | ||||
|                 case CONNECTION_FAIL: | ||||
|                 case ISafetyNetHelper.CONNECTION_FAIL: | ||||
|                 default: | ||||
|                     resid = R.string.safetyNet_api_error; | ||||
|                     break; | ||||
| @@ -28,7 +28,6 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber { | ||||
|     private ApplicationAdapter appAdapter; | ||||
|  | ||||
|     private SearchView.OnQueryTextListener searchListener; | ||||
|     private String lastFilter; | ||||
|  | ||||
|     @Override | ||||
|     public void onCreate(@Nullable Bundle savedInstanceState) { | ||||
| @@ -41,25 +40,22 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber { | ||||
|     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | ||||
|         View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false); | ||||
|         unbinder = ButterKnife.bind(this, view); | ||||
|         lastFilter = ""; | ||||
|  | ||||
|         mSwipeRefreshLayout.setRefreshing(true); | ||||
|         mSwipeRefreshLayout.setOnRefreshListener(() -> appAdapter.refresh()); | ||||
|  | ||||
|         appAdapter = new ApplicationAdapter(getActivity()); | ||||
|         appAdapter = new ApplicationAdapter(); | ||||
|         recyclerView.setAdapter(appAdapter); | ||||
|  | ||||
|         searchListener = new SearchView.OnQueryTextListener() { | ||||
|             @Override | ||||
|             public boolean onQueryTextSubmit(String query) { | ||||
|                 lastFilter = query; | ||||
|                 appAdapter.filter(query); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean onQueryTextChange(String newText) { | ||||
|                 lastFilter = newText; | ||||
|                 appAdapter.filter(newText); | ||||
|                 return false; | ||||
|             } | ||||
| @@ -84,9 +80,9 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onTopicPublished(Topic topic, Object result) { | ||||
|     public void onTopicPublished(Topic topic) { | ||||
|         mSwipeRefreshLayout.setRefreshing(false); | ||||
|         appAdapter.filter(lastFilter); | ||||
|         appAdapter.filter(null); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
							
								
								
									
										145
									
								
								src/full/java/com/topjohnwu/magisk/MagiskLogFragment.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/full/java/com/topjohnwu/magisk/MagiskLogFragment.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| package com.topjohnwu.magisk; | ||||
|  | ||||
| import android.Manifest; | ||||
| import android.os.Bundle; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.design.widget.Snackbar; | ||||
| import android.text.TextUtils; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.Menu; | ||||
| import android.view.MenuInflater; | ||||
| import android.view.MenuItem; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.HorizontalScrollView; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.ScrollView; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import com.topjohnwu.magisk.components.Fragment; | ||||
| import com.topjohnwu.magisk.components.SnackbarMaker; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.Calendar; | ||||
| import java.util.List; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import butterknife.Unbinder; | ||||
|  | ||||
| public class MagiskLogFragment extends Fragment { | ||||
|  | ||||
|     private Unbinder unbinder; | ||||
|  | ||||
|     @BindView(R.id.txtLog) TextView txtLog; | ||||
|     @BindView(R.id.svLog) ScrollView svLog; | ||||
|     @BindView(R.id.hsvLog) HorizontalScrollView hsvLog; | ||||
|     @BindView(R.id.progressBar) ProgressBar progressBar; | ||||
|  | ||||
|     @Nullable | ||||
|     @Override | ||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||||
|         View view = inflater.inflate(R.layout.fragment_magisk_log, container, false); | ||||
|         unbinder = ButterKnife.bind(this, view); | ||||
|         setHasOptionsMenu(true); | ||||
|         txtLog.setTextIsSelectable(true); | ||||
|         return view; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onStart() { | ||||
|         super.onStart(); | ||||
|         getActivity().setTitle(R.string.log); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onResume() { | ||||
|         super.onResume(); | ||||
|         readLogs(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onDestroyView() { | ||||
|         super.onDestroyView(); | ||||
|         unbinder.unbind(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { | ||||
|         inflater.inflate(R.menu.menu_log, menu); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         switch (item.getItemId()) { | ||||
|             case R.id.menu_refresh: | ||||
|                 readLogs(); | ||||
|                 return true; | ||||
|             case R.id.menu_save: | ||||
|                 runWithPermission(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, this::saveLogs); | ||||
|                 return true; | ||||
|             case R.id.menu_clear: | ||||
|                 clearLogs(); | ||||
|                 return true; | ||||
|             default: | ||||
|                 return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void readLogs() { | ||||
|         Shell.Async.su(new Shell.Async.Callback() { | ||||
|             @Override | ||||
|             public void onTaskResult(@Nullable List<String> out, @Nullable List<String> err) { | ||||
|                 progressBar.setVisibility(View.GONE); | ||||
|                 if (ShellUtils.isValidOutput(out)) { | ||||
|                     txtLog.setText(TextUtils.join("\n", out)); | ||||
|                 } else { | ||||
|                     txtLog.setText(R.string.log_is_empty); | ||||
|                 } | ||||
|                 svLog.postDelayed(() -> svLog.fullScroll(ScrollView.FOCUS_DOWN), 100); | ||||
|                 hsvLog.postDelayed(() -> hsvLog.fullScroll(ScrollView.FOCUS_LEFT), 100); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onTaskError(@NonNull Throwable throwable) { | ||||
|                 txtLog.setText(R.string.log_is_empty); | ||||
|             } | ||||
|         }, "cat " + Const.MAGISK_LOG + " | tail -n 5000"); | ||||
|     } | ||||
|  | ||||
|     public void saveLogs() { | ||||
|         Calendar now = Calendar.getInstance(); | ||||
|         String filename = Utils.fmt("magisk_log_%04d%02d%02d_%02d%02d%02d.log", | ||||
|                 now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1, | ||||
|                 now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY), | ||||
|                 now.get(Calendar.MINUTE), now.get(Calendar.SECOND)); | ||||
|  | ||||
|         File targetFile = new File(Const.EXTERNAL_PATH + "/logs", filename); | ||||
|         targetFile.getParentFile().mkdirs(); | ||||
|         try { | ||||
|             targetFile.createNewFile(); | ||||
|         } catch (IOException e) { | ||||
|             return; | ||||
|         } | ||||
|         Shell.Async.su(new Shell.Async.Callback() { | ||||
|             @Override | ||||
|             public void onTaskResult(@Nullable List<String> out, @Nullable List<String> err) { | ||||
|                 SnackbarMaker.make(txtLog, targetFile.getPath(), Snackbar.LENGTH_SHORT).show(); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onTaskError(@NonNull Throwable throwable) {} | ||||
|         }, "cat " + Const.MAGISK_LOG + " > " + targetFile); | ||||
|     } | ||||
|  | ||||
|     public void clearLogs() { | ||||
|         Shell.Async.su("echo -n > " + Const.MAGISK_LOG); | ||||
|         SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										292
									
								
								src/full/java/com/topjohnwu/magisk/MagiskManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								src/full/java/com/topjohnwu/magisk/MagiskManager.java
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,7 +1,6 @@ | ||||
| package com.topjohnwu.magisk; | ||||
|  | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.support.annotation.NonNull; | ||||
| @@ -16,16 +15,12 @@ import android.view.Menu; | ||||
| import android.view.MenuItem; | ||||
| 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.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
|  | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
|  | ||||
| @@ -33,8 +28,8 @@ public class MainActivity extends Activity | ||||
|         implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber { | ||||
|  | ||||
|     private final Handler mDrawerHandler = new Handler(); | ||||
|     private SharedPreferences prefs; | ||||
|     private int mDrawerItem; | ||||
|     private boolean fromShortcut = true; | ||||
|  | ||||
|     @BindView(R.id.toolbar) Toolbar toolbar; | ||||
|     @BindView(R.id.drawer_layout) DrawerLayout drawer; | ||||
| @@ -51,7 +46,6 @@ public class MainActivity extends Activity | ||||
|     protected void onCreate(final Bundle savedInstanceState) { | ||||
|  | ||||
|         MagiskManager mm = getMagiskManager(); | ||||
|         prefs = mm.prefs; | ||||
|  | ||||
|         if (!mm.hasInit) { | ||||
|             Intent intent = new Intent(this, SplashActivity.class); | ||||
| @@ -96,16 +90,6 @@ public class MainActivity extends Activity | ||||
|             navigate(getIntent().getStringExtra(Const.Key.OPEN_SECTION)); | ||||
|  | ||||
|         navigationView.setNavigationItemSelectedListener(this); | ||||
|  | ||||
|         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(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -118,7 +102,7 @@ public class MainActivity extends Activity | ||||
|     public void onBackPressed() { | ||||
|         if (drawer.isDrawerOpen(navigationView)) { | ||||
|             drawer.closeDrawer(navigationView); | ||||
|         } else if (mDrawerItem != R.id.magisk) { | ||||
|         } else if (mDrawerItem != R.id.magisk && !fromShortcut) { | ||||
|             navigate(R.id.magisk); | ||||
|         } else { | ||||
|             finish(); | ||||
| @@ -134,7 +118,7 @@ public class MainActivity extends Activity | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onTopicPublished(Topic topic, Object result) { | ||||
|     public void onTopicPublished(Topic topic) { | ||||
|         recreate(); | ||||
|     } | ||||
|  | ||||
| @@ -147,8 +131,8 @@ public class MainActivity extends Activity | ||||
|         MagiskManager mm = getMagiskManager(); | ||||
|         Menu menu = navigationView.getMenu(); | ||||
|         menu.findItem(R.id.magiskhide).setVisible( | ||||
|                 Shell.rootAccess() && mm.magiskVersionCode >= 1300 | ||||
|                         && prefs.getBoolean(Const.Key.MAGISKHIDE, false)); | ||||
|                 Shell.rootAccess() && mm.magiskVersionCode >= Const.MAGISK_VER.UNIFIED | ||||
|                         && mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false)); | ||||
|         menu.findItem(R.id.modules).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false) && | ||||
|                 Shell.rootAccess() && mm.magiskVersionCode >= 0); | ||||
|         menu.findItem(R.id.downloads).setVisible(!mm.prefs.getBoolean(Const.Key.COREONLY, false) | ||||
| @@ -162,9 +146,6 @@ public class MainActivity extends Activity | ||||
|         int itemId = R.id.magisk; | ||||
|         if (item != null) { | ||||
|             switch (item) { | ||||
|                 case "magisk": | ||||
|                     itemId = R.id.magisk; | ||||
|                     break; | ||||
|                 case "superuser": | ||||
|                     itemId = R.id.superuser; | ||||
|                     break; | ||||
| @@ -197,22 +178,23 @@ public class MainActivity extends Activity | ||||
|         navigationView.setCheckedItem(itemId); | ||||
|         switch (itemId) { | ||||
|             case R.id.magisk: | ||||
|                 displayFragment(new MagiskFragment(), "magisk", true); | ||||
|                 fromShortcut = false; | ||||
|                 displayFragment(new MagiskFragment(), true); | ||||
|                 break; | ||||
|             case R.id.superuser: | ||||
|                 displayFragment(new SuperuserFragment(), "superuser", true); | ||||
|                 displayFragment(new SuperuserFragment(), true); | ||||
|                 break; | ||||
|             case R.id.modules: | ||||
|                 displayFragment(new ModulesFragment(), "modules", true); | ||||
|                 displayFragment(new ModulesFragment(), true); | ||||
|                 break; | ||||
|             case R.id.downloads: | ||||
|                 displayFragment(new ReposFragment(), "downloads", true); | ||||
|                 displayFragment(new ReposFragment(), true); | ||||
|                 break; | ||||
|             case R.id.magiskhide: | ||||
|                 displayFragment(new MagiskHideFragment(), Const.Key.MAGISKHIDE, true); | ||||
|                 displayFragment(new MagiskHideFragment(), true); | ||||
|                 break; | ||||
|             case R.id.log: | ||||
|                 displayFragment(new LogFragment(), "log", false); | ||||
|                 displayFragment(new LogFragment(), false); | ||||
|                 break; | ||||
|             case R.id.settings: | ||||
|                 startActivity(new Intent(this, SettingsActivity.class)); | ||||
| @@ -225,12 +207,13 @@ public class MainActivity extends Activity | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void displayFragment(@NonNull Fragment navFragment, String tag, boolean setElevation) { | ||||
|         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); | ||||
|     private void displayFragment(@NonNull Fragment navFragment, boolean setElevation) { | ||||
|         supportInvalidateOptionsMenu(); | ||||
|         transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); | ||||
|         transaction.replace(R.id.content_frame, navFragment, tag).commitNow(); | ||||
|         if (setElevation) toolbar.setElevation(toolbarElevation); | ||||
|         else toolbar.setElevation(0); | ||||
|         getSupportFragmentManager() | ||||
|                 .beginTransaction() | ||||
|                 .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) | ||||
|                 .replace(R.id.content_frame, navFragment) | ||||
|                 .commitNow(); | ||||
|         toolbar.setElevation(setElevation ? toolbarElevation : 0); | ||||
|     } | ||||
| } | ||||
| @@ -21,7 +21,6 @@ import com.topjohnwu.magisk.components.Fragment; | ||||
| import com.topjohnwu.magisk.container.Module; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| @@ -40,7 +39,7 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber { | ||||
|     @BindView(R.id.empty_rv) TextView emptyRv; | ||||
|     @OnClick(R.id.fab) | ||||
|     public void selectFile() { | ||||
|         Utils.runWithPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, () -> { | ||||
|         runWithPermission(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> { | ||||
|             Intent intent = new Intent(Intent.ACTION_GET_CONTENT); | ||||
|             intent.setType("application/zip"); | ||||
|             startActivityForResult(intent, Const.ID.FETCH_ZIP); | ||||
| @@ -79,7 +78,7 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onTopicPublished(Topic topic, Object result) { | ||||
|     public void onTopicPublished(Topic topic) { | ||||
|         updateUI(); | ||||
|     } | ||||
|  | ||||
							
								
								
									
										26
									
								
								src/full/java/com/topjohnwu/magisk/NoUIActivity.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/full/java/com/topjohnwu/magisk/NoUIActivity.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| package com.topjohnwu.magisk; | ||||
|  | ||||
| import android.os.Bundle; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.v4.app.ActivityCompat; | ||||
|  | ||||
| import com.topjohnwu.magisk.components.Activity; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
|  | ||||
| public class NoUIActivity extends Activity { | ||||
|     @Override | ||||
|     protected void onCreate(@Nullable Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         String[] perms = getIntent().getStringArrayExtra(Const.Key.INTENT_PERM); | ||||
|         if (perms != null) { | ||||
|             ActivityCompat.requestPermissions(this, perms, 0); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { | ||||
|         super.onRequestPermissionsResult(requestCode, permissions, grantResults); | ||||
|         finish(); | ||||
|     } | ||||
| } | ||||
| @@ -27,6 +27,7 @@ import butterknife.Unbinder; | ||||
| public class ReposFragment extends Fragment implements Topic.Subscriber { | ||||
|  | ||||
|     private Unbinder unbinder; | ||||
|     private MagiskManager mm; | ||||
|     @BindView(R.id.recyclerView) RecyclerView recyclerView; | ||||
|     @BindView(R.id.empty_rv) TextView emptyRv; | ||||
|     @BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout; | ||||
| @@ -44,8 +45,9 @@ public class ReposFragment extends Fragment implements Topic.Subscriber { | ||||
|     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | ||||
|         View view = inflater.inflate(R.layout.fragment_repos, container, false); | ||||
|         unbinder = ButterKnife.bind(this, view); | ||||
|         mm = getApplication(); | ||||
|  | ||||
|         mSwipeRefreshLayout.setRefreshing(true); | ||||
|         mSwipeRefreshLayout.setRefreshing(mm.repoLoadDone.isPending()); | ||||
|  | ||||
|         mSwipeRefreshLayout.setOnRefreshListener(() -> { | ||||
|             recyclerView.setVisibility(View.VISIBLE); | ||||
| @@ -60,7 +62,7 @@ public class ReposFragment extends Fragment implements Topic.Subscriber { | ||||
|  | ||||
|     @Override | ||||
|     public void onResume() { | ||||
|         adapter = new ReposAdapter(getApplication().repoDB, getApplication().moduleMap); | ||||
|         adapter = new ReposAdapter(mm.repoDB, mm.moduleMap); | ||||
|         recyclerView.setAdapter(adapter); | ||||
|         super.onResume(); | ||||
|     } | ||||
| @@ -72,7 +74,7 @@ public class ReposFragment extends Fragment implements Topic.Subscriber { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onTopicPublished(Topic topic, Object result) { | ||||
|     public void onTopicPublished(Topic topic) { | ||||
|         mSwipeRefreshLayout.setRefreshing(false); | ||||
|         recyclerView.setVisibility(adapter.getItemCount() == 0 ? View.GONE : View.VISIBLE); | ||||
|         emptyRv.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE); | ||||
| @@ -80,7 +82,7 @@ public class ReposFragment extends Fragment implements Topic.Subscriber { | ||||
|  | ||||
|     @Override | ||||
|     public Topic[] getSubscription() { | ||||
|         return new Topic[] { getApplication().repoLoadDone }; | ||||
|         return new Topic[] { mm.repoLoadDone }; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -103,7 +105,6 @@ public class ReposFragment extends Fragment implements Topic.Subscriber { | ||||
|  | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         MagiskManager mm = getApplication(); | ||||
|         if (item.getItemId() == R.id.repo_sort) { | ||||
|             new AlertDialog.Builder(getActivity()) | ||||
|                 .setTitle(R.string.sorting_order) | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -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,27 +11,26 @@ 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.database.RepoDatabaseHelper; | ||||
| import com.topjohnwu.magisk.receivers.ShortcutReceiver; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.RootUtils; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| public class SplashActivity extends Activity { | ||||
|  | ||||
|     @Override | ||||
|     public int getDarkTheme() { | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|  | ||||
|         RootUtils.init(); | ||||
|         MagiskManager mm = getMagiskManager(); | ||||
|  | ||||
|         mm.repoDB = new RepoDatabaseHelper(this); | ||||
|         mm.loadMagiskInfo(); | ||||
|         mm.getDefaultInstallFlags(); | ||||
|         Utils.loadPrefs(); | ||||
|         mm.loadPrefs(); | ||||
|  | ||||
|         // Dynamic detect all locales | ||||
|         new LoadLocale().exec(); | ||||
| @@ -47,36 +42,24 @@ public class SplashActivity extends Activity { | ||||
|             getSystemService(NotificationManager.class).createNotificationChannel(channel); | ||||
|         } | ||||
|  | ||||
|         // Setup shortcuts | ||||
|         sendBroadcast(new Intent(this, ShortcutReceiver.class)); | ||||
|  | ||||
|         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(); | ||||
|         } | ||||
|  | ||||
|         // Write back default values | ||||
| @@ -46,7 +46,7 @@ public class SuLogFragment extends Fragment { | ||||
|         View v = inflater.inflate(R.layout.fragment_su_log, container, false); | ||||
|         unbinder = ButterKnife.bind(this, v); | ||||
|         mm = getApplication(); | ||||
|         adapter = new SuLogAdapter(mm.suDB); | ||||
|         adapter = new SuLogAdapter(mm.mDB); | ||||
|         recyclerView.setAdapter(adapter); | ||||
|  | ||||
|         updateList(); | ||||
| @@ -73,7 +73,7 @@ public class SuLogFragment extends Fragment { | ||||
|                 updateList(); | ||||
|                 return true; | ||||
|             case R.id.menu_clear: | ||||
|                 mm.suDB.clearLogs(); | ||||
|                 mm.mDB.clearLogs(); | ||||
|                 updateList(); | ||||
|                 return true; | ||||
|             default: | ||||
| @@ -34,13 +34,13 @@ public class SuperuserFragment extends Fragment { | ||||
|         PackageManager pm = getActivity().getPackageManager(); | ||||
|         MagiskManager mm = getApplication(); | ||||
|  | ||||
|         List<Policy> policyList = mm.suDB.getPolicyList(pm); | ||||
|         List<Policy> policyList = mm.mDB.getPolicyList(pm); | ||||
|  | ||||
|         if (policyList.size() == 0) { | ||||
|             emptyRv.setVisibility(View.VISIBLE); | ||||
|             recyclerView.setVisibility(View.GONE); | ||||
|         } else { | ||||
|             recyclerView.setAdapter(new PolicyAdapter(policyList, mm.suDB, pm)); | ||||
|             recyclerView.setAdapter(new PolicyAdapter(policyList, mm.mDB, pm)); | ||||
|             emptyRv.setVisibility(View.GONE); | ||||
|             recyclerView.setVisibility(View.VISIBLE); | ||||
|         } | ||||
| @@ -1,9 +1,7 @@ | ||||
| package com.topjohnwu.magisk.adapters; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.content.pm.ApplicationInfo; | ||||
| import android.content.pm.PackageManager; | ||||
| import android.support.design.widget.Snackbar; | ||||
| import android.support.v7.widget.RecyclerView; | ||||
| import android.text.TextUtils; | ||||
| import android.view.LayoutInflater; | ||||
| @@ -14,12 +12,10 @@ import android.widget.Filter; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.TextView; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| 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.Topic; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| @@ -32,25 +28,19 @@ import butterknife.ButterKnife; | ||||
|  | ||||
| public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> { | ||||
|  | ||||
|     private List<ApplicationInfo> mOriginalList, mList; | ||||
|     private List<String> mHideList; | ||||
|     private List<ApplicationInfo> fullList, showList; | ||||
|     private List<String> hideList; | ||||
|     private PackageManager pm; | ||||
|     private ApplicationFilter filter; | ||||
|     private Topic magiskHideDone; | ||||
|  | ||||
|     public ApplicationAdapter(Context context) { | ||||
|         mOriginalList = mList = Collections.emptyList(); | ||||
|         mHideList = Collections.emptyList(); | ||||
|     public ApplicationAdapter() { | ||||
|         fullList = showList = Collections.emptyList(); | ||||
|         hideList = Collections.emptyList(); | ||||
|         filter = new ApplicationFilter(); | ||||
|         pm = context.getPackageManager(); | ||||
|         magiskHideDone = Utils.getMagiskManager(context).magiskHideDone; | ||||
|         pm = MagiskManager.get().getPackageManager(); | ||||
|         new LoadApps().exec(); | ||||
|     } | ||||
|  | ||||
|     private boolean lowercaseContains(CharSequence string, CharSequence nonNullLowercaseSearch) { | ||||
|         return !TextUtils.isEmpty(string) && string.toString().toLowerCase().contains(nonNullLowercaseSearch); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | ||||
|         View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false); | ||||
| @@ -59,41 +49,28 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter. | ||||
|  | ||||
|     @Override | ||||
|     public void onBindViewHolder(final ViewHolder holder, int position) { | ||||
|         ApplicationInfo info = mList.get(position); | ||||
|         ApplicationInfo info = showList.get(position); | ||||
|  | ||||
|         holder.appIcon.setImageDrawable(info.loadIcon(pm)); | ||||
|         holder.appName.setText(info.loadLabel(pm)); | ||||
|         holder.appPackage.setText(info.packageName); | ||||
|  | ||||
|         // Remove all listeners | ||||
|         holder.itemView.setOnClickListener(null); | ||||
|         holder.checkBox.setOnCheckedChangeListener(null); | ||||
|  | ||||
|         if (Const.SN_DEFAULTLIST.contains(info.packageName)) { | ||||
|             holder.checkBox.setChecked(true); | ||||
|             holder.checkBox.setEnabled(false); | ||||
|             holder.itemView.setOnClickListener(v -> | ||||
|                 SnackbarMaker.make(holder.itemView, | ||||
|                         R.string.safetyNet_hide_notice, Snackbar.LENGTH_LONG).show() | ||||
|             ); | ||||
|         } else { | ||||
|             holder.checkBox.setEnabled(true); | ||||
|             holder.checkBox.setChecked(mHideList.contains(info.packageName)); | ||||
|             holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> { | ||||
|                 if (isChecked) { | ||||
|                     Shell.Async.su("magiskhide --add " + info.packageName); | ||||
|                     mHideList.add(info.packageName); | ||||
|                 } else { | ||||
|                     Shell.Async.su("magiskhide --rm " + info.packageName); | ||||
|                     mHideList.remove(info.packageName); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         holder.checkBox.setChecked(hideList.contains(info.packageName)); | ||||
|         holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> { | ||||
|             if (isChecked) { | ||||
|                 Shell.Async.su("magiskhide --add " + info.packageName); | ||||
|                 hideList.add(info.packageName); | ||||
|             } else { | ||||
|                 Shell.Async.su("magiskhide --rm " + info.packageName); | ||||
|                 hideList.remove(info.packageName); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         return mList.size(); | ||||
|         return showList.size(); | ||||
|     } | ||||
|  | ||||
|     public void filter(String constraint) { | ||||
| @@ -119,17 +96,21 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter. | ||||
|  | ||||
|     private class ApplicationFilter extends Filter { | ||||
|  | ||||
|         private boolean lowercaseContains(String s, CharSequence filter) { | ||||
|             return !TextUtils.isEmpty(s) && s.toLowerCase().contains(filter); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected FilterResults performFiltering(CharSequence constraint) { | ||||
|             if (constraint == null || constraint.length() == 0) { | ||||
|                 mList = mOriginalList; | ||||
|                 showList = fullList; | ||||
|             } else { | ||||
|                 mList = new ArrayList<>(); | ||||
|                 showList = new ArrayList<>(); | ||||
|                 String filter = constraint.toString().toLowerCase(); | ||||
|                 for (ApplicationInfo info : mOriginalList) { | ||||
|                     if (lowercaseContains(info.loadLabel(pm), filter) | ||||
|                 for (ApplicationInfo info : fullList) { | ||||
|                     if (lowercaseContains(info.loadLabel(pm).toString(), filter) | ||||
|                             || lowercaseContains(info.packageName, filter)) { | ||||
|                         mList.add(info); | ||||
|                         showList.add(info); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @@ -146,22 +127,32 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter. | ||||
|  | ||||
|         @Override | ||||
|         protected Void doInBackground(Void... voids) { | ||||
|             mOriginalList = pm.getInstalledApplications(0); | ||||
|             for (Iterator<ApplicationInfo> i = mOriginalList.iterator(); i.hasNext(); ) { | ||||
|             fullList = pm.getInstalledApplications(0); | ||||
|             hideList = Shell.Sync.su("magiskhide --ls"); | ||||
|             for (Iterator<ApplicationInfo> i = fullList.iterator(); i.hasNext(); ) { | ||||
|                 ApplicationInfo info = i.next(); | ||||
|                 if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) { | ||||
|                     i.remove(); | ||||
|                 } | ||||
|             } | ||||
|             Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase() | ||||
|                     .compareTo(b.loadLabel(pm).toString().toLowerCase())); | ||||
|             mHideList = Shell.Sync.su("magiskhide --ls"); | ||||
|             Collections.sort(fullList, (a, b) -> { | ||||
|                 boolean ah = hideList.contains(a.packageName); | ||||
|                 boolean bh = hideList.contains(b.packageName); | ||||
|                 if (ah == bh) { | ||||
|                     return a.loadLabel(pm).toString().toLowerCase().compareTo( | ||||
|                             b.loadLabel(pm).toString().toLowerCase()); | ||||
|                 } else if (ah) { | ||||
|                     return -1; | ||||
|                 } else { | ||||
|                     return 1; | ||||
|                 } | ||||
|             }); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         protected void onPostExecute(Void v) { | ||||
|             magiskHideDone.publish(false); | ||||
|             MagiskManager.get().magiskHideDone.publish(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -16,7 +16,7 @@ import com.topjohnwu.magisk.components.AlertDialogBuilder; | ||||
| import com.topjohnwu.magisk.components.ExpandableView; | ||||
| import com.topjohnwu.magisk.components.SnackbarMaker; | ||||
| import com.topjohnwu.magisk.container.Policy; | ||||
| import com.topjohnwu.magisk.database.SuDatabaseHelper; | ||||
| import com.topjohnwu.magisk.database.MagiskDatabaseHelper; | ||||
|  | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| @@ -28,11 +28,11 @@ import butterknife.ButterKnife; | ||||
| public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder> { | ||||
|  | ||||
|     private List<Policy> policyList; | ||||
|     private SuDatabaseHelper dbHelper; | ||||
|     private MagiskDatabaseHelper dbHelper; | ||||
|     private PackageManager pm; | ||||
|     private Set<Policy> expandList = new HashSet<>(); | ||||
|  | ||||
|     public PolicyAdapter(List<Policy> list, SuDatabaseHelper db, PackageManager pm) { | ||||
|     public PolicyAdapter(List<Policy> list, MagiskDatabaseHelper db, PackageManager pm) { | ||||
|         policyList = list; | ||||
|         dbHelper = db; | ||||
|         this.pm = pm; | ||||
| @@ -13,7 +13,7 @@ import android.widget.TextView; | ||||
| import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.components.ExpandableView; | ||||
| import com.topjohnwu.magisk.container.SuLogEntry; | ||||
| import com.topjohnwu.magisk.database.SuDatabaseHelper; | ||||
| import com.topjohnwu.magisk.database.MagiskDatabaseHelper; | ||||
|  | ||||
| import java.util.Collections; | ||||
| import java.util.HashSet; | ||||
| @@ -27,10 +27,10 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S | ||||
|  | ||||
|     private List<List<Integer>> logEntryList; | ||||
|     private Set<Integer> itemExpanded, sectionExpanded; | ||||
|     private SuDatabaseHelper suDB; | ||||
|     private MagiskDatabaseHelper suDB; | ||||
|     private Cursor suLogCursor = null; | ||||
|  | ||||
|     public SuLogAdapter(SuDatabaseHelper db) { | ||||
|     public SuLogAdapter(MagiskDatabaseHelper db) { | ||||
|         suDB = db; | ||||
|         logEntryList = Collections.emptyList(); | ||||
|         sectionExpanded = new HashSet<>(); | ||||
| @@ -0,0 +1,84 @@ | ||||
| package com.topjohnwu.magisk.asyncs; | ||||
|  | ||||
| import android.app.Activity; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.ISafetyNetHelper; | ||||
| import com.topjohnwu.magisk.utils.WebService; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
|  | ||||
| import java.io.BufferedInputStream; | ||||
| import java.io.BufferedOutputStream; | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.net.HttpURLConnection; | ||||
|  | ||||
| import dalvik.system.DexClassLoader; | ||||
|  | ||||
| public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> { | ||||
|  | ||||
|     public static final File dexPath = | ||||
|             new File(MagiskManager.get().getFilesDir().getParent() + "/snet", "snet.apk"); | ||||
|     private ISafetyNetHelper helper; | ||||
|  | ||||
|     public CheckSafetyNet(Activity activity) { | ||||
|         super(activity); | ||||
|     } | ||||
|  | ||||
|     private void dlSnet() throws Exception { | ||||
|         Shell.Sync.sh("rm -rf " + dexPath.getParent()); | ||||
|         dexPath.getParentFile().mkdir(); | ||||
|         HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null); | ||||
|         try ( | ||||
|                 OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath)); | ||||
|                 InputStream in = new BufferedInputStream(conn.getInputStream())) { | ||||
|             ShellUtils.pump(in, out); | ||||
|         } finally { | ||||
|             conn.disconnect(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void dyload() throws Exception { | ||||
|         DexClassLoader loader = new DexClassLoader(dexPath.getPath(), dexPath.getParent(), | ||||
|                 null, ISafetyNetHelper.class.getClassLoader()); | ||||
|         Class<?> clazz = loader.loadClass("com.topjohnwu.snet.SafetyNetHelper"); | ||||
|         helper = (ISafetyNetHelper) clazz.getConstructors()[0] | ||||
|                 .newInstance(getActivity(), (ISafetyNetHelper.Callback) | ||||
|                         code -> MagiskManager.get().safetyNetDone.publish(false, code)); | ||||
|         if (helper.getVersion() != Const.SNET_VER) { | ||||
|             throw new Exception(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected Exception doInBackground(Void... voids) { | ||||
|         try { | ||||
|             try { | ||||
|                 dyload(); | ||||
|             } catch (Exception e) { | ||||
|                 // If dynamic load failed, try re-downloading and reload | ||||
|                 dlSnet(); | ||||
|                 dyload(); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             return e; | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onPostExecute(Exception e) { | ||||
|         if (e == null) { | ||||
|             helper.attest(); | ||||
|         } else { | ||||
|             e.printStackTrace(); | ||||
|             MagiskManager.get().safetyNetDone.publish(false, -1); | ||||
|         } | ||||
|         super.onPostExecute(e); | ||||
|     } | ||||
| } | ||||
| @@ -42,11 +42,14 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> { | ||||
|             mm.remoteMagiskVersionString = magisk.getString("version"); | ||||
|             mm.remoteMagiskVersionCode = magisk.getInt("versionCode"); | ||||
|             mm.magiskLink = magisk.getString("link"); | ||||
|             mm.releaseNoteLink = magisk.getString("note"); | ||||
|             mm.magiskNoteLink = magisk.getString("note"); | ||||
|             JSONObject manager = json.getJSONObject("app"); | ||||
|             mm.remoteManagerVersionString = manager.getString("version"); | ||||
|             mm.remoteManagerVersionCode = manager.getInt("versionCode"); | ||||
|             mm.managerLink = manager.getString("link"); | ||||
|             mm.managerNoteLink = manager.getString("note"); | ||||
|             JSONObject uninstaller = json.getJSONObject("uninstaller"); | ||||
|             mm.uninstallerLink = uninstaller.getString("link"); | ||||
|         } catch (JSONException ignored) {} | ||||
|         return null; | ||||
|     } | ||||
| @@ -54,7 +57,7 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> { | ||||
|     @Override | ||||
|     protected void onPostExecute(Void v) { | ||||
|         MagiskManager mm = MagiskManager.get(); | ||||
|         if (showNotification && mm.prefs.getBoolean(Const.Key.UPDATE_NOTIFICATION, true)) { | ||||
|         if (showNotification) { | ||||
|             if (BuildConfig.VERSION_CODE < mm.remoteManagerVersionCode) { | ||||
|                 ShowUI.managerUpdateNotification(); | ||||
|             } else if (mm.magiskVersionCode < mm.remoteMagiskVersionCode) { | ||||
| @@ -7,6 +7,7 @@ import android.view.View; | ||||
|  | ||||
| import com.topjohnwu.magisk.FlashActivity; | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.components.SnackbarMaker; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.Utils; | ||||
| import com.topjohnwu.magisk.utils.ZipUtils; | ||||
| @@ -39,8 +40,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> { | ||||
|  | ||||
|     private boolean unzipAndCheck() throws Exception { | ||||
|         ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true); | ||||
|         String s = Utils.cmd("head -n 1 " + new File(mCachedFile.getParentFile(), "updater-script")); | ||||
|         return s != null && s.contains("#MAGISK"); | ||||
|         return ShellUtils.fastCmdResult("grep -q '#MAGISK' " + new File(mCachedFile.getParentFile(), "updater-script")); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -93,7 +93,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> { | ||||
|         switch (result) { | ||||
|             case -1: | ||||
|                 console.add("! Installation failed"); | ||||
|                 Utils.showUriSnack(getActivity(), mUri); | ||||
|                 SnackbarMaker.showUri(getActivity(), mUri); | ||||
|                 break; | ||||
|             case 0: | ||||
|                 console.add("! This zip is not a Magisk Module!"); | ||||
							
								
								
									
										95
									
								
								src/full/java/com/topjohnwu/magisk/asyncs/HideManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/full/java/com/topjohnwu/magisk/asyncs/HideManager.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| package com.topjohnwu.magisk.asyncs; | ||||
|  | ||||
| import android.app.Activity; | ||||
| import android.app.ProgressDialog; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import com.topjohnwu.magisk.MagiskManager; | ||||
| import com.topjohnwu.magisk.R; | ||||
| import com.topjohnwu.magisk.utils.Const; | ||||
| import com.topjohnwu.magisk.utils.PatchAPK; | ||||
| import com.topjohnwu.magisk.utils.RootUtils; | ||||
| import com.topjohnwu.superuser.Shell; | ||||
| import com.topjohnwu.superuser.ShellUtils; | ||||
| import com.topjohnwu.superuser.io.SuFile; | ||||
| import com.topjohnwu.superuser.io.SuFileOutputStream; | ||||
|  | ||||
| import java.io.FileNotFoundException; | ||||
| import java.security.SecureRandom; | ||||
|  | ||||
| public class HideManager extends ParallelTask<Void, Void, Boolean> { | ||||
|  | ||||
|     private ProgressDialog dialog; | ||||
|  | ||||
|     public HideManager(Activity activity) { | ||||
|         super(activity); | ||||
|     } | ||||
|  | ||||
|     private String genPackageName(String prefix, int length) { | ||||
|         StringBuilder builder = new StringBuilder(length); | ||||
|         builder.append(prefix); | ||||
|         length -= prefix.length(); | ||||
|         SecureRandom random = new SecureRandom(); | ||||
|         String base = "abcdefghijklmnopqrstuvwxyz"; | ||||
|         String alpha = base + base.toUpperCase(); | ||||
|         String full = alpha + "0123456789.........."; | ||||
|         char next, prev = '\0'; | ||||
|         for (int i = 0; i < length; ++i) { | ||||
|             if (prev == '.' || i == length - 1 || i == 0) { | ||||
|                 next = alpha.charAt(random.nextInt(alpha.length())); | ||||
|             } else { | ||||
|                 next = full.charAt(random.nextInt(full.length())); | ||||
|             } | ||||
|             builder.append(next); | ||||
|             prev = next; | ||||
|         } | ||||
|         return builder.toString(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onPreExecute() { | ||||
|         dialog = ProgressDialog.show(getActivity(), | ||||
|                 getActivity().getString(R.string.hide_manager_toast), | ||||
|                 getActivity().getString(R.string.hide_manager_toast2)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected Boolean doInBackground(Void... voids) { | ||||
|         MagiskManager mm = MagiskManager.get(); | ||||
|  | ||||
|         // Generate a new app with random package name | ||||
|         SuFile repack = new SuFile("/data/local/tmp/repack.apk"); | ||||
|         String pkg = genPackageName("com.", Const.ORIG_PKG_NAME.length()); | ||||
|  | ||||
|         try { | ||||
|             if (!PatchAPK.patchPackageID( | ||||
|                     mm.getPackageCodePath(), | ||||
|                     new SuFileOutputStream(repack), | ||||
|                     Const.ORIG_PKG_NAME, pkg)) | ||||
|                 return false; | ||||
|         } catch (FileNotFoundException e) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Install the application | ||||
|         if (!ShellUtils.fastCmdResult(Shell.getShell(), "pm install " + repack)) | ||||
|             return false; | ||||
|  | ||||
|         repack.delete(); | ||||
|  | ||||
|         mm.mDB.setStrings(Const.Key.SU_MANAGER, pkg); | ||||
|         mm.dumpPrefs(); | ||||
|         RootUtils.uninstallPkg(Const.ORIG_PKG_NAME); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected void onPostExecute(Boolean b) { | ||||
|         dialog.dismiss(); | ||||
|         if (!b) { | ||||
|             MagiskManager.toast(R.string.hide_manager_fail_toast, Toast.LENGTH_LONG); | ||||
|         } | ||||
|         super.onPostExecute(b); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										327
									
								
								src/full/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								src/full/java/com/topjohnwu/magisk/asyncs/InstallMagisk.java
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user