mirror of
https://github.com/topjohnwu/Magisk
synced 2025-11-06 21:02:30 +01:00
Compare commits
88 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 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -6,7 +6,7 @@
|
|||||||
app/release
|
app/release
|
||||||
*.hprof
|
*.hprof
|
||||||
.externalNativeBuild/
|
.externalNativeBuild/
|
||||||
src/main/assets
|
src/full/res/raw/util_functions.sh
|
||||||
public.certificate.x509.pem
|
public.certificate.x509.pem
|
||||||
private.key.pk8
|
private.key.pk8
|
||||||
*.apk
|
*.apk
|
||||||
|
|||||||
@@ -1,2 +1,7 @@
|
|||||||
# Magisk Manager
|
# Magisk Manager
|
||||||
This repo is no longer an independent component. It is a submodule of the [Magisk Project](https://github.com/topjohnwu/Magisk).
|
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.
|
||||||
|
|||||||
35
build.gradle
35
build.gradle
@@ -8,8 +8,6 @@ android {
|
|||||||
applicationId "com.topjohnwu.magisk"
|
applicationId "com.topjohnwu.magisk"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion rootProject.ext.compileSdkVersion
|
targetSdkVersion rootProject.ext.compileSdkVersion
|
||||||
versionCode 115
|
|
||||||
versionName "5.7.0"
|
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
argument('butterknife.debuggable', 'false')
|
argument('butterknife.debuggable', 'false')
|
||||||
@@ -24,6 +22,20 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.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 {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
@@ -39,14 +51,15 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation project(':utils')
|
fullImplementation project(':utils')
|
||||||
implementation 'com.github.topjohnwu:libsu:1.1.1'
|
implementation "com.android.support:support-core-utils:${rootProject.ext.supportLibVersion}"
|
||||||
implementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}"
|
fullImplementation "com.android.support:preference-v7:${rootProject.ext.supportLibVersion}"
|
||||||
implementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}"
|
fullImplementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}"
|
||||||
implementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
|
fullImplementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}"
|
||||||
implementation "com.android.support:support-v4:${rootProject.ext.supportLibVersion}"
|
fullImplementation "com.android.support:design:${rootProject.ext.supportLibVersion}"
|
||||||
implementation 'com.jakewharton:butterknife:8.8.1'
|
fullImplementation 'com.github.topjohnwu:libsu:1.2.0'
|
||||||
implementation 'com.atlassian.commonmark:commonmark:0.10.0'
|
fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0'
|
||||||
implementation 'org.kamranzafar:jtar:2.3'
|
fullImplementation 'org.kamranzafar:jtar:2.3'
|
||||||
|
fullImplementation 'com.jakewharton:butterknife:8.8.1'
|
||||||
annotationProcessor 'com.jakewharton:butterknife-compiler: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>
|
||||||
@@ -31,7 +31,7 @@ public class AboutActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDarkTheme() {
|
public int getDarkTheme() {
|
||||||
return R.style.AppTheme_Transparent_Dark;
|
return R.style.AppTheme_StatusBar_Dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -3,6 +3,7 @@ package com.topjohnwu.magisk;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -17,6 +18,7 @@ import com.topjohnwu.magisk.asyncs.FlashZip;
|
|||||||
import com.topjohnwu.magisk.asyncs.InstallMagisk;
|
import com.topjohnwu.magisk.asyncs.InstallMagisk;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
import com.topjohnwu.magisk.utils.RootUtils;
|
||||||
import com.topjohnwu.superuser.CallbackList;
|
import com.topjohnwu.superuser.CallbackList;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
@@ -77,7 +79,7 @@ public class FlashActivity extends Activity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDarkTheme() {
|
public int getDarkTheme() {
|
||||||
return R.style.AppTheme_Transparent_Dark;
|
return R.style.AppTheme_StatusBar_Dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -113,13 +115,18 @@ public class FlashActivity extends Activity {
|
|||||||
case Const.Value.FLASH_ZIP:
|
case Const.Value.FLASH_ZIP:
|
||||||
new FlashZip(this, uri, console, logs).exec();
|
new FlashZip(this, uri, console, logs).exec();
|
||||||
break;
|
break;
|
||||||
case Const.Value.PATCH_BOOT:
|
case Const.Value.UNINSTALL:
|
||||||
new InstallMagisk(this, console, logs, uri, (Uri) intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT))
|
new UninstallMagisk(this, uri, console, logs).exec();
|
||||||
.exec();
|
|
||||||
break;
|
break;
|
||||||
case Const.Value.FLASH_MAGISK:
|
case Const.Value.FLASH_MAGISK:
|
||||||
new InstallMagisk(this, console, logs, uri, intent.getStringExtra(Const.Key.FLASH_SET_BOOT))
|
new InstallMagisk(this, console, logs, uri, InstallMagisk.DIRECT_MODE).exec();
|
||||||
.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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,4 +135,21 @@ public class FlashActivity extends Activity {
|
|||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
// Prevent user accidentally press back button
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,10 +24,12 @@ import com.topjohnwu.magisk.components.AlertDialogBuilder;
|
|||||||
import com.topjohnwu.magisk.components.ExpandableView;
|
import com.topjohnwu.magisk.components.ExpandableView;
|
||||||
import com.topjohnwu.magisk.components.Fragment;
|
import com.topjohnwu.magisk.components.Fragment;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
|
||||||
import com.topjohnwu.magisk.utils.ShowUI;
|
import com.topjohnwu.magisk.utils.ShowUI;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import butterknife.BindColor;
|
import butterknife.BindColor;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
@@ -38,14 +40,6 @@ import butterknife.Unbinder;
|
|||||||
public class MagiskFragment extends Fragment
|
public class MagiskFragment extends Fragment
|
||||||
implements Topic.Subscriber, SwipeRefreshLayout.OnRefreshListener, ExpandableView {
|
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 Container expandableContainer = new Container();
|
||||||
|
|
||||||
private MagiskManager mm;
|
private MagiskManager mm;
|
||||||
@@ -259,17 +253,22 @@ public class MagiskFragment extends Fragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shownDialog && (mm.remoteMagiskVersionCode > mm.magiskVersionCode
|
|
||||||
|| mm.remoteManagerVersionCode > BuildConfig.VERSION_CODE)) {
|
|
||||||
install();
|
|
||||||
}
|
|
||||||
|
|
||||||
magiskUpdateIcon.setImageResource(image);
|
magiskUpdateIcon.setImageResource(image);
|
||||||
magiskUpdateIcon.setColorFilter(color);
|
magiskUpdateIcon.setColorFilter(color);
|
||||||
magiskUpdateIcon.setVisibility(View.VISIBLE);
|
magiskUpdateIcon.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
magiskUpdateProgress.setVisibility(View.GONE);
|
magiskUpdateProgress.setVisibility(View.GONE);
|
||||||
mSwipeRefreshLayout.setRefreshing(false);
|
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) {
|
private void updateSafetyNetUI(int response) {
|
||||||
@@ -279,12 +278,12 @@ public class MagiskFragment extends Fragment
|
|||||||
safetyNetStatusText.setText(R.string.safetyNet_check_success);
|
safetyNetStatusText.setText(R.string.safetyNet_check_success);
|
||||||
|
|
||||||
boolean b;
|
boolean b;
|
||||||
b = (response & CTS_PASS) != 0;
|
b = (response & ISafetyNetHelper.CTS_PASS) != 0;
|
||||||
ctsStatusText.setText("ctsProfile: " + b);
|
ctsStatusText.setText("ctsProfile: " + b);
|
||||||
ctsStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
ctsStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||||
ctsStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
ctsStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||||
|
|
||||||
b = (response & BASIC_PASS) != 0;
|
b = (response & ISafetyNetHelper.BASIC_PASS) != 0;
|
||||||
basicStatusText.setText("basicIntegrity: " + b);
|
basicStatusText.setText("basicIntegrity: " + b);
|
||||||
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
basicStatusIcon.setImageResource(b ? R.drawable.ic_check_circle : R.drawable.ic_cancel);
|
||||||
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
basicStatusIcon.setColorFilter(b ? colorOK : colorBad);
|
||||||
@@ -293,16 +292,16 @@ public class MagiskFragment extends Fragment
|
|||||||
} else {
|
} else {
|
||||||
@StringRes int resid;
|
@StringRes int resid;
|
||||||
switch (response) {
|
switch (response) {
|
||||||
case CAUSE_SERVICE_DISCONNECTED:
|
case ISafetyNetHelper.CAUSE_SERVICE_DISCONNECTED:
|
||||||
resid = R.string.safetyNet_network_loss;
|
resid = R.string.safetyNet_network_loss;
|
||||||
break;
|
break;
|
||||||
case CAUSE_NETWORK_LOST:
|
case ISafetyNetHelper.CAUSE_NETWORK_LOST:
|
||||||
resid = R.string.safetyNet_service_disconnected;
|
resid = R.string.safetyNet_service_disconnected;
|
||||||
break;
|
break;
|
||||||
case RESPONSE_ERR:
|
case ISafetyNetHelper.RESPONSE_ERR:
|
||||||
resid = R.string.safetyNet_res_invalid;
|
resid = R.string.safetyNet_res_invalid;
|
||||||
break;
|
break;
|
||||||
case CONNECTION_FAIL:
|
case ISafetyNetHelper.CONNECTION_FAIL:
|
||||||
default:
|
default:
|
||||||
resid = R.string.safetyNet_api_error;
|
resid = R.string.safetyNet_api_error;
|
||||||
break;
|
break;
|
||||||
@@ -28,7 +28,6 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
|
|||||||
private ApplicationAdapter appAdapter;
|
private ApplicationAdapter appAdapter;
|
||||||
|
|
||||||
private SearchView.OnQueryTextListener searchListener;
|
private SearchView.OnQueryTextListener searchListener;
|
||||||
private String lastFilter;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
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) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false);
|
View view = inflater.inflate(R.layout.fragment_magisk_hide, container, false);
|
||||||
unbinder = ButterKnife.bind(this, view);
|
unbinder = ButterKnife.bind(this, view);
|
||||||
lastFilter = "";
|
|
||||||
|
|
||||||
mSwipeRefreshLayout.setRefreshing(true);
|
mSwipeRefreshLayout.setRefreshing(true);
|
||||||
mSwipeRefreshLayout.setOnRefreshListener(() -> appAdapter.refresh());
|
mSwipeRefreshLayout.setOnRefreshListener(() -> appAdapter.refresh());
|
||||||
|
|
||||||
appAdapter = new ApplicationAdapter(getActivity());
|
appAdapter = new ApplicationAdapter();
|
||||||
recyclerView.setAdapter(appAdapter);
|
recyclerView.setAdapter(appAdapter);
|
||||||
|
|
||||||
searchListener = new SearchView.OnQueryTextListener() {
|
searchListener = new SearchView.OnQueryTextListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextSubmit(String query) {
|
public boolean onQueryTextSubmit(String query) {
|
||||||
lastFilter = query;
|
|
||||||
appAdapter.filter(query);
|
appAdapter.filter(query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextChange(String newText) {
|
public boolean onQueryTextChange(String newText) {
|
||||||
lastFilter = newText;
|
|
||||||
appAdapter.filter(newText);
|
appAdapter.filter(newText);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -86,7 +82,7 @@ public class MagiskHideFragment extends Fragment implements Topic.Subscriber {
|
|||||||
@Override
|
@Override
|
||||||
public void onTopicPublished(Topic topic) {
|
public void onTopicPublished(Topic topic) {
|
||||||
mSwipeRefreshLayout.setRefreshing(false);
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
appAdapter.filter(lastFilter);
|
appAdapter.filter(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@ import android.view.Menu;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.asyncs.MarkDownWindow;
|
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
@@ -91,12 +90,6 @@ public class MainActivity extends Activity
|
|||||||
navigate(getIntent().getStringExtra(Const.Key.OPEN_SECTION));
|
navigate(getIntent().getStringExtra(Const.Key.OPEN_SECTION));
|
||||||
|
|
||||||
navigationView.setNavigationItemSelectedListener(this);
|
navigationView.setNavigationItemSelectedListener(this);
|
||||||
|
|
||||||
if (mm.prefs.getInt(Const.Key.APP_VER, -1) < BuildConfig.VERSION_CODE) {
|
|
||||||
mm.prefs.edit().putInt(Const.Key.APP_VER, BuildConfig.VERSION_CODE).apply();
|
|
||||||
new MarkDownWindow(this, getString(R.string.app_changelog),
|
|
||||||
getResources().openRawResource(R.raw.changelog)).exec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -21,7 +21,6 @@ import com.topjohnwu.magisk.components.Fragment;
|
|||||||
import com.topjohnwu.magisk.container.Module;
|
import com.topjohnwu.magisk.container.Module;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -40,7 +39,7 @@ public class ModulesFragment extends Fragment implements Topic.Subscriber {
|
|||||||
@BindView(R.id.empty_rv) TextView emptyRv;
|
@BindView(R.id.empty_rv) TextView emptyRv;
|
||||||
@OnClick(R.id.fab)
|
@OnClick(R.id.fab)
|
||||||
public void selectFile() {
|
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 intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
intent.setType("application/zip");
|
intent.setType("application/zip");
|
||||||
startActivityForResult(intent, Const.ID.FETCH_ZIP);
|
startActivityForResult(intent, Const.ID.FETCH_ZIP);
|
||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,33 +1,36 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.ListPreference;
|
import android.support.v14.preference.SwitchPreference;
|
||||||
import android.preference.Preference;
|
|
||||||
import android.preference.PreferenceCategory;
|
|
||||||
import android.preference.PreferenceFragment;
|
|
||||||
import android.preference.PreferenceScreen;
|
|
||||||
import android.preference.SwitchPreference;
|
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.support.v7.preference.ListPreference;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
|
import android.support.v7.preference.PreferenceFragmentCompat;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
import com.topjohnwu.magisk.asyncs.CheckUpdates;
|
||||||
import com.topjohnwu.magisk.asyncs.HideManager;
|
import com.topjohnwu.magisk.asyncs.HideManager;
|
||||||
import com.topjohnwu.magisk.components.Activity;
|
import com.topjohnwu.magisk.components.Activity;
|
||||||
import com.topjohnwu.magisk.receivers.ManagerUpdate;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.FingerprintHelper;
|
import com.topjohnwu.magisk.utils.FingerprintHelper;
|
||||||
|
import com.topjohnwu.magisk.utils.RootUtils;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
import com.topjohnwu.magisk.utils.Topic;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -41,7 +44,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getDarkTheme() {
|
public int getDarkTheme() {
|
||||||
return R.style.AppTheme_Transparent_Dark;
|
return R.style.AppTheme_StatusBar_Dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -63,7 +66,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
setFloating();
|
setFloating();
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
getFragmentManager().beginTransaction().add(R.id.container, new SettingsFragment()).commit();
|
getSupportFragmentManager().beginTransaction().add(R.id.container, new SettingsFragment()).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -78,7 +81,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
return new Topic[] { getMagiskManager().reloadActivity };
|
return new Topic[] { getMagiskManager().reloadActivity };
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SettingsFragment extends PreferenceFragment
|
public static class SettingsFragment extends PreferenceFragmentCompat
|
||||||
implements SharedPreferences.OnSharedPreferenceChangeListener, Topic.Subscriber {
|
implements SharedPreferences.OnSharedPreferenceChangeListener, Topic.Subscriber {
|
||||||
|
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
@@ -90,9 +93,8 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
private PreferenceCategory generalCatagory;
|
private PreferenceCategory generalCatagory;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||||
super.onCreate(savedInstanceState);
|
setPreferencesFromResource(R.xml.app_settings, rootKey);
|
||||||
addPreferencesFromResource(R.xml.app_settings);
|
|
||||||
mm = Utils.getMagiskManager(getActivity());
|
mm = Utils.getMagiskManager(getActivity());
|
||||||
prefs = mm.prefs;
|
prefs = mm.prefs;
|
||||||
prefScreen = getPreferenceScreen();
|
prefScreen = getPreferenceScreen();
|
||||||
@@ -126,13 +128,13 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
EditText url = v.findViewById(R.id.custom_url);
|
EditText url = v.findViewById(R.id.custom_url);
|
||||||
url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
|
url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
|
||||||
new AlertDialog.Builder(getActivity())
|
new AlertDialog.Builder(getActivity())
|
||||||
.setTitle(R.string.settings_update_custom)
|
.setTitle(R.string.settings_update_custom)
|
||||||
.setView(v)
|
.setView(v)
|
||||||
.setPositiveButton(R.string.ok, (d, i) ->
|
.setPositiveButton(R.string.ok, (d, i) ->
|
||||||
prefs.edit().putString(Const.Key.CUSTOM_CHANNEL,
|
prefs.edit().putString(Const.Key.CUSTOM_CHANNEL,
|
||||||
url.getText().toString()).apply())
|
url.getText().toString()).apply())
|
||||||
.setNegativeButton(R.string.close, null)
|
.setNegativeButton(R.string.close, null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -166,14 +168,18 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
} else {
|
} else {
|
||||||
if (Utils.checkNetworkStatus()) {
|
if (Utils.checkNetworkStatus()) {
|
||||||
restoreManager.setOnPreferenceClickListener((pref) -> {
|
restoreManager.setOnPreferenceClickListener((pref) -> {
|
||||||
Utils.runWithPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, () -> {
|
Utils.dlAndReceive(
|
||||||
Intent intent = new Intent(mm, ManagerUpdate.class);
|
getActivity(), new DownloadReceiver() {
|
||||||
intent.putExtra(Const.Key.INTENT_SET_LINK, mm.managerLink);
|
@Override
|
||||||
intent.putExtra(Const.Key.INTENT_SET_FILENAME,
|
public void onDownloadDone(Context context, Uri uri) {
|
||||||
Utils.fmt("MagiskManager-v%s(%d).apk",
|
mm.dumpPrefs();
|
||||||
mm.remoteManagerVersionString, mm.remoteManagerVersionCode));
|
if (ShellUtils.fastCmdResult("pm install " + uri.getPath()))
|
||||||
mm.sendBroadcast(intent);
|
RootUtils.uninstallPkg(context.getPackageName());
|
||||||
});
|
}
|
||||||
|
},
|
||||||
|
mm.managerLink,
|
||||||
|
Utils.fmt("MagiskManager-v%s.apk", mm.remoteManagerVersionString)
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -200,13 +206,9 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setLocalePreference(ListPreference lp) {
|
private void setLocalePreference(ListPreference lp) {
|
||||||
boolean isNew = lp == null;
|
|
||||||
if (isNew) {
|
|
||||||
lp = new ListPreference(getActivity());
|
|
||||||
}
|
|
||||||
CharSequence[] entries = new CharSequence[mm.locales.size() + 1];
|
CharSequence[] entries = new CharSequence[mm.locales.size() + 1];
|
||||||
CharSequence[] entryValues = new CharSequence[mm.locales.size() + 1];
|
CharSequence[] entryValues = new CharSequence[mm.locales.size() + 1];
|
||||||
entries[0] = getString(R.string.system_default);
|
entries[0] = Utils.getLocaleString(MagiskManager.defaultLocale, R.string.system_default);
|
||||||
entryValues[0] = "";
|
entryValues[0] = "";
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (Locale locale : mm.locales) {
|
for (Locale locale : mm.locales) {
|
||||||
@@ -215,26 +217,21 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
}
|
}
|
||||||
lp.setEntries(entries);
|
lp.setEntries(entries);
|
||||||
lp.setEntryValues(entryValues);
|
lp.setEntryValues(entryValues);
|
||||||
lp.setTitle(R.string.language);
|
|
||||||
lp.setKey(Const.Key.LOCALE);
|
|
||||||
lp.setSummary(MagiskManager.locale.getDisplayName(MagiskManager.locale));
|
lp.setSummary(MagiskManager.locale.getDisplayName(MagiskManager.locale));
|
||||||
if (isNew) {
|
|
||||||
generalCatagory.addPreference(lp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
super.onResume();
|
|
||||||
prefs.registerOnSharedPreferenceChangeListener(this);
|
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||||
subscribeTopics();
|
subscribeTopics();
|
||||||
|
return super.onCreateView(inflater, container, savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onDestroyView() {
|
||||||
prefs.unregisterOnSharedPreferenceChangeListener(this);
|
prefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
unsubscribeTopics();
|
unsubscribeTopics();
|
||||||
super.onPause();
|
super.onDestroyView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -244,7 +241,7 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
case Const.Key.DARK_THEME:
|
case Const.Key.DARK_THEME:
|
||||||
mm.isDarkTheme = prefs.getBoolean(key, false);
|
mm.isDarkTheme = prefs.getBoolean(key, false);
|
||||||
mm.reloadActivity.publish(false);
|
mm.reloadActivity.publish(false);
|
||||||
break;
|
return;
|
||||||
case Const.Key.COREONLY:
|
case Const.Key.COREONLY:
|
||||||
if (prefs.getBoolean(key, false)) {
|
if (prefs.getBoolean(key, false)) {
|
||||||
try {
|
try {
|
||||||
@@ -265,12 +262,12 @@ public class SettingsActivity extends Activity implements Topic.Subscriber {
|
|||||||
case Const.Key.HOSTS:
|
case Const.Key.HOSTS:
|
||||||
if (prefs.getBoolean(key, false)) {
|
if (prefs.getBoolean(key, false)) {
|
||||||
Shell.Async.su(
|
Shell.Async.su(
|
||||||
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE(),
|
"cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE,
|
||||||
"mount -o bind " + Const.MAGISK_HOST_FILE() + " /system/etc/hosts");
|
"mount -o bind " + Const.MAGISK_HOST_FILE + " /system/etc/hosts");
|
||||||
} else {
|
} else {
|
||||||
Shell.Async.su(
|
Shell.Async.su(
|
||||||
"umount -l /system/etc/hosts",
|
"umount -l /system/etc/hosts",
|
||||||
"rm -f " + Const.MAGISK_HOST_FILE());
|
"rm -f " + Const.MAGISK_HOST_FILE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Const.Key.ROOT_ACCESS:
|
case Const.Key.ROOT_ACCESS:
|
||||||
@@ -14,6 +14,7 @@ import com.topjohnwu.magisk.components.Activity;
|
|||||||
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
import com.topjohnwu.magisk.database.RepoDatabaseHelper;
|
||||||
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
|
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
import com.topjohnwu.magisk.utils.RootUtils;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
@@ -23,12 +24,13 @@ public class SplashActivity extends Activity {
|
|||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
RootUtils.init();
|
||||||
MagiskManager mm = getMagiskManager();
|
MagiskManager mm = getMagiskManager();
|
||||||
|
|
||||||
mm.repoDB = new RepoDatabaseHelper(this);
|
mm.repoDB = new RepoDatabaseHelper(this);
|
||||||
mm.loadMagiskInfo();
|
mm.loadMagiskInfo();
|
||||||
mm.getDefaultInstallFlags();
|
mm.getDefaultInstallFlags();
|
||||||
Utils.loadPrefs();
|
mm.loadPrefs();
|
||||||
|
|
||||||
// Dynamic detect all locales
|
// Dynamic detect all locales
|
||||||
new LoadLocale().exec();
|
new LoadLocale().exec();
|
||||||
@@ -58,8 +60,6 @@ public class SplashActivity extends Activity {
|
|||||||
mm.setupUpdateCheck();
|
mm.setupUpdateCheck();
|
||||||
// Fire asynctasks
|
// Fire asynctasks
|
||||||
loadModuleTask.exec();
|
loadModuleTask.exec();
|
||||||
// Check dtbo status
|
|
||||||
Utils.patchDTBO();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write back default values
|
// Write back default values
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.topjohnwu.magisk.adapters;
|
package com.topjohnwu.magisk.adapters;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
@@ -13,11 +12,10 @@ import android.widget.Filter;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.R;
|
import com.topjohnwu.magisk.R;
|
||||||
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
import com.topjohnwu.magisk.asyncs.ParallelTask;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Topic;
|
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -30,25 +28,19 @@ import butterknife.ButterKnife;
|
|||||||
|
|
||||||
public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> {
|
public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> {
|
||||||
|
|
||||||
private List<ApplicationInfo> mOriginalList, mList;
|
private List<ApplicationInfo> fullList, showList;
|
||||||
private List<String> mHideList;
|
private List<String> hideList;
|
||||||
private PackageManager pm;
|
private PackageManager pm;
|
||||||
private ApplicationFilter filter;
|
private ApplicationFilter filter;
|
||||||
private Topic magiskHideDone;
|
|
||||||
|
|
||||||
public ApplicationAdapter(Context context) {
|
public ApplicationAdapter() {
|
||||||
mOriginalList = mList = Collections.emptyList();
|
fullList = showList = Collections.emptyList();
|
||||||
mHideList = Collections.emptyList();
|
hideList = Collections.emptyList();
|
||||||
filter = new ApplicationFilter();
|
filter = new ApplicationFilter();
|
||||||
pm = context.getPackageManager();
|
pm = MagiskManager.get().getPackageManager();
|
||||||
magiskHideDone = Utils.getMagiskManager(context).magiskHideDone;
|
|
||||||
new LoadApps().exec();
|
new LoadApps().exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean lowercaseContains(CharSequence string, CharSequence nonNullLowercaseSearch) {
|
|
||||||
return !TextUtils.isEmpty(string) && string.toString().toLowerCase().contains(nonNullLowercaseSearch);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false);
|
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_app, parent, false);
|
||||||
@@ -57,28 +49,28 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
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.appIcon.setImageDrawable(info.loadIcon(pm));
|
||||||
holder.appName.setText(info.loadLabel(pm));
|
holder.appName.setText(info.loadLabel(pm));
|
||||||
holder.appPackage.setText(info.packageName);
|
holder.appPackage.setText(info.packageName);
|
||||||
|
|
||||||
holder.checkBox.setOnCheckedChangeListener(null);
|
holder.checkBox.setOnCheckedChangeListener(null);
|
||||||
holder.checkBox.setChecked(mHideList.contains(info.packageName));
|
holder.checkBox.setChecked(hideList.contains(info.packageName));
|
||||||
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
|
holder.checkBox.setOnCheckedChangeListener((v, isChecked) -> {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
Shell.Async.su("magiskhide --add " + info.packageName);
|
Shell.Async.su("magiskhide --add " + info.packageName);
|
||||||
mHideList.add(info.packageName);
|
hideList.add(info.packageName);
|
||||||
} else {
|
} else {
|
||||||
Shell.Async.su("magiskhide --rm " + info.packageName);
|
Shell.Async.su("magiskhide --rm " + info.packageName);
|
||||||
mHideList.remove(info.packageName);
|
hideList.remove(info.packageName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return mList.size();
|
return showList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void filter(String constraint) {
|
public void filter(String constraint) {
|
||||||
@@ -104,17 +96,21 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
|
|||||||
|
|
||||||
private class ApplicationFilter extends Filter {
|
private class ApplicationFilter extends Filter {
|
||||||
|
|
||||||
|
private boolean lowercaseContains(String s, CharSequence filter) {
|
||||||
|
return !TextUtils.isEmpty(s) && s.toLowerCase().contains(filter);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FilterResults performFiltering(CharSequence constraint) {
|
protected FilterResults performFiltering(CharSequence constraint) {
|
||||||
if (constraint == null || constraint.length() == 0) {
|
if (constraint == null || constraint.length() == 0) {
|
||||||
mList = mOriginalList;
|
showList = fullList;
|
||||||
} else {
|
} else {
|
||||||
mList = new ArrayList<>();
|
showList = new ArrayList<>();
|
||||||
String filter = constraint.toString().toLowerCase();
|
String filter = constraint.toString().toLowerCase();
|
||||||
for (ApplicationInfo info : mOriginalList) {
|
for (ApplicationInfo info : fullList) {
|
||||||
if (lowercaseContains(info.loadLabel(pm), filter)
|
if (lowercaseContains(info.loadLabel(pm).toString(), filter)
|
||||||
|| lowercaseContains(info.packageName, filter)) {
|
|| lowercaseContains(info.packageName, filter)) {
|
||||||
mList.add(info);
|
showList.add(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,22 +127,32 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... voids) {
|
protected Void doInBackground(Void... voids) {
|
||||||
mOriginalList = pm.getInstalledApplications(0);
|
fullList = pm.getInstalledApplications(0);
|
||||||
for (Iterator<ApplicationInfo> i = mOriginalList.iterator(); i.hasNext(); ) {
|
hideList = Shell.Sync.su("magiskhide --ls");
|
||||||
|
for (Iterator<ApplicationInfo> i = fullList.iterator(); i.hasNext(); ) {
|
||||||
ApplicationInfo info = i.next();
|
ApplicationInfo info = i.next();
|
||||||
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) {
|
if (Const.HIDE_BLACKLIST.contains(info.packageName) || !info.enabled) {
|
||||||
i.remove();
|
i.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(mOriginalList, (a, b) -> a.loadLabel(pm).toString().toLowerCase()
|
Collections.sort(fullList, (a, b) -> {
|
||||||
.compareTo(b.loadLabel(pm).toString().toLowerCase()));
|
boolean ah = hideList.contains(a.packageName);
|
||||||
mHideList = Shell.Sync.su("magiskhide --ls");
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Void v) {
|
protected void onPostExecute(Void v) {
|
||||||
magiskHideDone.publish(false);
|
MagiskManager.get().magiskHideDone.publish(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import android.app.Activity;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
|
import com.topjohnwu.magisk.utils.ISafetyNetHelper;
|
||||||
import com.topjohnwu.magisk.utils.WebService;
|
import com.topjohnwu.magisk.utils.WebService;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
import com.topjohnwu.superuser.ShellUtils;
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
@@ -12,10 +13,8 @@ import java.io.BufferedInputStream;
|
|||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
|
||||||
import dalvik.system.DexClassLoader;
|
import dalvik.system.DexClassLoader;
|
||||||
@@ -24,32 +23,33 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
|||||||
|
|
||||||
public static final File dexPath =
|
public static final File dexPath =
|
||||||
new File(MagiskManager.get().getFilesDir().getParent() + "/snet", "snet.apk");
|
new File(MagiskManager.get().getFilesDir().getParent() + "/snet", "snet.apk");
|
||||||
private DexClassLoader loader;
|
private ISafetyNetHelper helper;
|
||||||
private Class<?> helperClazz, callbackClazz;
|
|
||||||
|
|
||||||
public CheckSafetyNet(Activity activity) {
|
public CheckSafetyNet(Activity activity) {
|
||||||
super(activity);
|
super(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dlSnet() throws IOException {
|
private void dlSnet() throws Exception {
|
||||||
Shell.Sync.sh("rm -rf " + dexPath.getParent());
|
Shell.Sync.sh("rm -rf " + dexPath.getParent());
|
||||||
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
|
|
||||||
dexPath.getParentFile().mkdir();
|
dexPath.getParentFile().mkdir();
|
||||||
|
HttpURLConnection conn = WebService.request(Const.Url.SNET_URL, null);
|
||||||
try (
|
try (
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(dexPath));
|
||||||
InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
InputStream in = new BufferedInputStream(conn.getInputStream())) {
|
||||||
ShellUtils.pump(in, out);
|
ShellUtils.pump(in, out);
|
||||||
|
} finally {
|
||||||
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
conn.disconnect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dyload() throws Exception {
|
private void dyload() throws Exception {
|
||||||
loader = new DexClassLoader(dexPath.getPath(), dexPath.getParent(),
|
DexClassLoader loader = new DexClassLoader(dexPath.getPath(), dexPath.getParent(),
|
||||||
null, ClassLoader.getSystemClassLoader());
|
null, ISafetyNetHelper.class.getClassLoader());
|
||||||
helperClazz = loader.loadClass(Const.SNET_PKG + ".SafetyNetHelper");
|
Class<?> clazz = loader.loadClass("com.topjohnwu.snet.SafetyNetHelper");
|
||||||
callbackClazz = loader.loadClass(Const.SNET_PKG + ".SafetyNetCallback");
|
helper = (ISafetyNetHelper) clazz.getConstructors()[0]
|
||||||
int snet_ver = (int) helperClazz.getMethod("getVersion").invoke(null);
|
.newInstance(getActivity(), (ISafetyNetHelper.Callback)
|
||||||
if (snet_ver != Const.SNET_VER) {
|
code -> MagiskManager.get().safetyNetDone.publish(false, code));
|
||||||
|
if (helper.getVersion() != Const.SNET_VER) {
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,21 +72,13 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Exception err) {
|
protected void onPostExecute(Exception e) {
|
||||||
MagiskManager mm = MagiskManager.get();
|
if (e == null) {
|
||||||
try {
|
helper.attest();
|
||||||
if (err != null) throw err;
|
} else {
|
||||||
Object helper = helperClazz.getConstructors()[0].newInstance(
|
|
||||||
getActivity(), dexPath.getPath(), Proxy.newProxyInstance(
|
|
||||||
loader, new Class[] { callbackClazz }, (proxy, method, args) -> {
|
|
||||||
mm.safetyNetDone.publish(false, args[0]);
|
|
||||||
return null;
|
|
||||||
}));
|
|
||||||
helperClazz.getMethod("attest").invoke(helper);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
mm.safetyNetDone.publish(false, -1);
|
MagiskManager.get().safetyNetDone.publish(false, -1);
|
||||||
}
|
}
|
||||||
super.onPostExecute(err);
|
super.onPostExecute(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,11 +42,14 @@ public class CheckUpdates extends ParallelTask<Void, Void, Void> {
|
|||||||
mm.remoteMagiskVersionString = magisk.getString("version");
|
mm.remoteMagiskVersionString = magisk.getString("version");
|
||||||
mm.remoteMagiskVersionCode = magisk.getInt("versionCode");
|
mm.remoteMagiskVersionCode = magisk.getInt("versionCode");
|
||||||
mm.magiskLink = magisk.getString("link");
|
mm.magiskLink = magisk.getString("link");
|
||||||
mm.releaseNoteLink = magisk.getString("note");
|
mm.magiskNoteLink = magisk.getString("note");
|
||||||
JSONObject manager = json.getJSONObject("app");
|
JSONObject manager = json.getJSONObject("app");
|
||||||
mm.remoteManagerVersionString = manager.getString("version");
|
mm.remoteManagerVersionString = manager.getString("version");
|
||||||
mm.remoteManagerVersionCode = manager.getInt("versionCode");
|
mm.remoteManagerVersionCode = manager.getInt("versionCode");
|
||||||
mm.managerLink = manager.getString("link");
|
mm.managerLink = manager.getString("link");
|
||||||
|
mm.managerNoteLink = manager.getString("note");
|
||||||
|
JSONObject uninstaller = json.getJSONObject("uninstaller");
|
||||||
|
mm.uninstallerLink = uninstaller.getString("link");
|
||||||
} catch (JSONException ignored) {}
|
} catch (JSONException ignored) {}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import android.view.View;
|
|||||||
|
|
||||||
import com.topjohnwu.magisk.FlashActivity;
|
import com.topjohnwu.magisk.FlashActivity;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
|
import com.topjohnwu.magisk.components.SnackbarMaker;
|
||||||
import com.topjohnwu.magisk.utils.Const;
|
import com.topjohnwu.magisk.utils.Const;
|
||||||
import com.topjohnwu.magisk.utils.Utils;
|
import com.topjohnwu.magisk.utils.Utils;
|
||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
@@ -39,8 +40,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
|
|
||||||
private boolean unzipAndCheck() throws Exception {
|
private boolean unzipAndCheck() throws Exception {
|
||||||
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
ZipUtils.unzip(mCachedFile, mCachedFile.getParentFile(), "META-INF/com/google/android", true);
|
||||||
String s = Utils.cmd("head -n 1 " + new File(mCachedFile.getParentFile(), "updater-script"));
|
return ShellUtils.fastCmdResult("grep -q '#MAGISK' " + new File(mCachedFile.getParentFile(), "updater-script"));
|
||||||
return s != null && s.contains("#MAGISK");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -93,7 +93,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
switch (result) {
|
switch (result) {
|
||||||
case -1:
|
case -1:
|
||||||
console.add("! Installation failed");
|
console.add("! Installation failed");
|
||||||
Utils.showUriSnack(getActivity(), mUri);
|
SnackbarMaker.showUri(getActivity(), mUri);
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
console.add("! This zip is not a Magisk Module!");
|
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