Compare commits

...

38 Commits

Author SHA1 Message Date
topjohnwu
cfe32f1a70 Update Magisk Manager changelogs 2018-09-20 22:34:09 -04:00
Taras
d877f5d5c6 update Ukrainian strings 2018-09-20 16:56:17 -04:00
yuchenlin
0ab6ffefb4 utils/misc.c: prevent file staying opened when function leaving
The utils function may be called in any situation, such as in daemon. We
should guarantee that all the resource got from this function released
normally.

Signed-off-by: yuchenlin <npes87184@gmail.com>
2018-09-20 16:55:48 -04:00
topjohnwu
a292a1d23a Cleanup and add new rules
Close #607
2018-09-20 16:55:16 -04:00
topjohnwu
3f87f6aee3 Fix output in Magisk Manager if no root exists 2018-09-20 16:21:22 -04:00
topjohnwu
04bcd145d3 Add a.a alias to BootSigner 2018-09-20 15:37:59 -04:00
topjohnwu
244e811291 Remove icon padding in preference screen
Courtesy of https://stackoverflow.com/a/51568782
2018-09-19 00:06:14 -04:00
topjohnwu
ac7467fb59 Optimize boot signing to use as little memory as possible 2018-09-18 23:48:21 -04:00
topjohnwu
2c0436216f Prevent null strings in modules/repos
Close #620, close #621
2018-09-18 10:04:12 -04:00
topjohnwu
017fbf267b Fix small theme config issue 2018-09-17 23:29:38 -04:00
topjohnwu
e6afbf2ec0 Force remove busybox from APK 2018-09-17 23:03:37 -04:00
topjohnwu
906b4aad9e New method of communication
Introduce a new communication method between Magisk and Magisk Manager.

Magisk used to hardcode classnames and send broadcast/start activities to
specific components. This new method makes no assumption of any class names,
so Magisk Manager can easily be fully obfuscated.

In addition, the new method connects Magisk and Magisk Manager with random
abstract Linux sockets instead of socket files in filesystems, bypassing
file system complexities (selinux, permissions and such)
2018-09-16 04:16:18 -04:00
topjohnwu
4cf8d41f6a Fix FlashActivity crash 2018-09-16 00:18:34 -04:00
topjohnwu
47c860142e Use ClassMaps to prevent errors 2018-09-16 00:08:13 -04:00
topjohnwu
2fba3f213b Use proper socket address length 2018-09-15 02:49:19 -04:00
topjohnwu
af7c6f9fce Fix FlashActivity crash 2018-09-15 01:45:10 -04:00
topjohnwu
78534deab6 Excessive obfuscation when building in release mode
Close #606
2018-09-14 23:00:39 -04:00
topjohnwu
6710314832 Allow all context to SIGCLD magisk
Fix #596
2018-09-11 11:04:51 -04:00
topjohnwu
0cd4fa6fa0 Simplify SignAPK code 2018-09-11 10:48:36 -04:00
topjohnwu
065949496e Migrate to AndroidX support library 2018-09-10 02:27:45 -04:00
topjohnwu
39c82576ae Prevent warning
Close #524
2018-09-09 12:36:42 -04:00
John Wu
37221a508d Update README.MD 2018-09-09 12:25:22 -04:00
John Wu
6b43a32a10 Delete repo_description.png 2018-09-09 10:41:02 -04:00
ImgBotApp
d7cd1ff142 [ImgBot] optimizes images
*Total -- 990.86kb -> 771.48kb (22.14%)

/docs/images/flashfire.png -- 223.55kb -> 153.39kb (31.39%)
/docs/images/repo_description.png -- 38.55kb -> 27.31kb (29.15%)
/docs/images/manager_reboot.png -- 147.43kb -> 111.50kb (24.37%)
/docs/images/install_inactive_slot.png -- 123.15kb -> 99.79kb (18.97%)
/docs/images/restore_img.png -- 134.17kb -> 109.22kb (18.59%)
/docs/images/disable_auto_ota.png -- 160.04kb -> 132.05kb (17.49%)
/docs/images/ota_done.png -- 163.97kb -> 138.22kb (15.71%)
2018-09-09 10:40:40 -04:00
Sandro Jäckel
659d947863 Updated German translations 2018-09-09 10:40:33 -04:00
Rom
39be7a6288 Update stub French translation 2018-09-09 00:38:47 -04:00
Rom
8ac976c579 Update French translation (#576) 2018-09-09 00:38:33 -04:00
Vladimír Kubala
70fd432c57 Update Slovak translation 2018-09-09 00:38:25 -04:00
Jonas Schubert
00135f2f49 updated full\res\values.de\strings.xml 2018-09-09 00:38:11 -04:00
Albert I
9b944bc29c Update Indonesian translations
Signed-off-by: Albert I <krascgq@outlook.co.id>
2018-09-09 00:38:02 -04:00
topjohnwu
d520b3d2a0 Request storage permission when patching boot images 2018-09-08 23:27:19 -04:00
topjohnwu
6f41d9855b Randomize service names
Fix Aniplex Game detections.
Close #502, close #513
2018-09-08 23:17:00 -04:00
topjohnwu
2d7c1da741 Better support for external config file 2018-09-06 14:25:35 -04:00
topjohnwu
c0f45b6b1e Add resetprop magic 2018-09-06 02:57:02 -04:00
topjohnwu
7a0025673c Use libsystemproperties in resetprop
Upstream to latest Android Pie
2018-09-06 02:57:02 -04:00
topjohnwu
ad7ec79903 Support custom config paths 2018-09-05 14:24:28 -04:00
topjohnwu
0543239cca Do not merge binaries if fake symlink 2018-09-01 11:15:05 -04:00
topjohnwu
ff3dad2457 Prevent upgrading database before upgrading to v17.0 2018-09-01 10:46:13 -04:00
174 changed files with 5350 additions and 3674 deletions

View File

@@ -1,7 +1,7 @@
# Magisk # Magisk
[XDA Announcement Thread](https://forum.xda-developers.com/apps/magisk/official-magisk-v7-universal-systemless-t3473445)
## Building Environment Requirements ## Building Environment Requirements
1. Python 3.5+: run `build.py` script 1. Python 3.5+: run `build.py` script
2. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips 2. Java Development Kit (JDK) 8: Compile Magisk Manager and sign zips
3. Latest Android SDK: set `ANDROID_HOME` environment variable to the path to Android SDK 3. Latest Android SDK: set `ANDROID_HOME` environment variable to the path to Android SDK
@@ -9,10 +9,16 @@
5. (Windows Only) Python package Colorama: Install with `pip install colorama`, used for ANSI color codes 5. (Windows Only) Python package Colorama: Install with `pip install colorama`, used for ANSI color codes
## Building Notes and Instructions ## Building Notes and Instructions
1. Building is supported on macOS, Linux, and Windows using the custom NDK: [FrankeNDK](https://github.com/topjohnwu/FrankeNDK). 1. Clone sources with submodules: `git clone --recurse-submodules https://github.com/topjohnwu/Magisk.git`
2. Set configurations in `config.prop`. A sample file `config.prop.sample` is provided as an example. 2. Building is supported on macOS, Linux, and Windows. Official releases are built and tested with [FrankeNDK](https://github.com/topjohnwu/FrankeNDK); point `ANDROID_NDK_HOME` to FrankeNDK if you want to use it for compiling.
3. Run `build.py` with argument `-h` to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h` 3. Set configurations in `config.prop`. A sample file `config.prop.sample` is provided as an example.
4. By default, `build.py` build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (via the `-r, --release` flag), you need a Java Keystore file `release-key.jks` (only `JKS` format is supported) to sign APKs and zips. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually). 4. Run `build.py` with argument `-h` to see the built-in help message. The `-h` option also works for each supported actions, e.g. `./build.py binary -h`
5. By default, `build.py` build binaries and Magisk Manager in debug mode. If you want to build Magisk Manager in release mode (via the `-r, --release` flag), you need a Java Keystore file `release-key.jks` (only `JKS` format is supported) to sign APKs and zips. For more information, check out [Google's Official Documentation](https://developer.android.com/studio/publish/app-signing.html#signing-manually).
## Bug Reports
**Make sure to install the latest [Canary Build](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337) before reporting any bugs!** Please **DO NOT** report bugs that is already fixed upstream.
Follow the instructions in the [Canary Channel XDA Thread](https://forum.xda-developers.com/apps/magisk/dev-magisk-canary-channel-bleeding-edge-t3839337), and report a bug either by opening an issue on GitHub or directly in the thread.
## Documentation ## Documentation
[Link to Documentation](docs/README.MD) [Link to Documentation](docs/README.MD)

View File

@@ -1,7 +1,8 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
def configProps = new Properties() def configProps = new Properties()
configProps.load(new FileInputStream(rootProject.file('config.prop'))) def configPath = project.hasProperty('configPath') ? project.configPath : rootProject.file('config.prop')
configProps.load(new FileInputStream(configPath))
android { android {
compileSdkVersion rootProject.ext.compileSdkVersion compileSdkVersion rootProject.ext.compileSdkVersion
@@ -70,14 +71,12 @@ android {
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
fullImplementation project(':utils') fullImplementation project(':utils')
implementation "com.android.support:support-core-utils:${rootProject.ext.supportLibVersion}" implementation "androidx.core:core:${rootProject.ext.androidXVersion}"
fullImplementation "com.android.support:preference-v7:${rootProject.ext.supportLibVersion}" fullImplementation "androidx.preference:preference:${rootProject.ext.androidXVersion}"
fullImplementation "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}" fullImplementation "androidx.recyclerview:recyclerview:${rootProject.ext.androidXVersion}"
fullImplementation "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}" fullImplementation "androidx.cardview:cardview:${rootProject.ext.androidXVersion}"
fullImplementation "com.android.support:design:${rootProject.ext.supportLibVersion}" fullImplementation "com.google.android.material:material:${rootProject.ext.androidXVersion}"
fullImplementation 'com.github.topjohnwu:libsu:2.0.1' fullImplementation 'com.github.topjohnwu:libsu:2.0.2'
fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0' fullImplementation 'com.atlassian.commonmark:commonmark:0.11.0'
fullImplementation 'org.kamranzafar:jtar:2.3' fullImplementation 'org.kamranzafar:jtar:2.3'
fullImplementation 'com.jakewharton:butterknife:8.8.1'
fullAnnotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
} }

View File

@@ -16,19 +16,20 @@
# public *; # public *;
#} #}
# Don't obfuscate, we are open source anyway :)
-dontobfuscate
# BouncyCastle # BouncyCastle
-keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.**SHA1** { *; } -keep class org.bouncycastle.jcajce.provider.asymmetric.rsa.**SHA1** { *; }
-keep class org.bouncycastle.jcajce.provider.asymmetric.RSA** { *; } -keep class org.bouncycastle.jcajce.provider.asymmetric.RSA** { *; }
-keep class org.bouncycastle.jcajce.provider.digest.SHA1** { *; } -keep class org.bouncycastle.jcajce.provider.digest.SHA1** { *; }
-dontwarn javax.naming.** -dontwarn javax.naming.**
# Gson # Snet extention
-keepattributes Signature -keepclassmembers class com.topjohnwu.magisk.utils.ISafetyNetHelper { *; }
# Strip logging # Strip logging
-assumenosideeffects class com.topjohnwu.magisk.utils.Logger { -assumenosideeffects class com.topjohnwu.magisk.utils.Logger {
public *** debug(...); public *** debug(...);
} }
# Excessive obfuscation
-repackageclasses 'a'
-allowaccessmodification

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.topjohnwu.magisk"> package="com.topjohnwu.magisk">
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
@@ -8,15 +9,18 @@
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<application <application
android:name=".MagiskManager" android:name="a.q"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<!-- Activities -->
<activity <activity
android:name=".MainActivity" android:name="a.b"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:exported="true" /> android:exported="true" />
<activity <activity
android:name=".SplashActivity" android:name="a.c"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:exported="true" android:exported="true"
android:theme="@style/SplashTheme"> android:theme="@style/SplashTheme">
@@ -26,53 +30,68 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".AboutActivity" android:name="a.d"
android:theme="@style/AppTheme.StatusBar" /> android:theme="@style/AppTheme.StatusBar" />
<activity <activity
android:name=".DonationActivity" android:name="a.e"
android:theme="@style/AppTheme.StatusBar"/> android:theme="@style/AppTheme.StatusBar"/>
<activity <activity
android:name=".FlashActivity" android:name="a.f"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="nosensor" android:screenOrientation="nosensor"
android:theme="@style/AppTheme.StatusBar" /> android:theme="@style/AppTheme.StatusBar" />
<activity <activity
android:name=".NoUIActivity" android:name="a.g"
android:theme="@style/AppTheme.Translucent" /> android:theme="@style/AppTheme.Translucent" />
<!-- Superuser -->
<activity <activity
android:name=".superuser.RequestActivity" android:name="a.p"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:launchMode="singleTask" android:launchMode="singleTask"
android:taskAffinity="internal.superuser" android:taskAffinity="internal.superuser"
android:theme="@style/SuRequest" /> android:theme="@style/SuRequest" />
<activity
android:name=".superuser.RequestActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:taskAffinity="internal.superuser"
android:theme="@style/AppTheme.Translucent" />
<receiver android:name=".superuser.SuReceiver" /> <receiver android:name=".superuser.SuReceiver" />
<receiver android:name=".receivers.BootReceiver">
<!-- Receiver -->
<receiver android:name="a.h">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.PackageReceiver"> <receiver android:name="a.i">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" /> <action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" /> <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED" />
<data android:scheme="package" /> <data android:scheme="package" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".receivers.ManagerUpdate" /> <receiver android:name="a.j" />
<receiver android:name=".receivers.RebootReceiver" /> <receiver android:name="a.k" />
<receiver android:name=".receivers.ShortcutReceiver"> <receiver android:name="a.l">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.LOCALE_CHANGED" /> <action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- Service -->
<service <service
android:name=".services.OnBootService" android:name="a.m"
android:exported="true" android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" /> android:permission="android.permission.BIND_JOB_SERVICE" />
<service <service
android:name=".services.UpdateCheckService" android:name="a.n"
android:exported="true" android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE" /> android:permission="android.permission.BIND_JOB_SERVICE" />

View File

@@ -0,0 +1,10 @@
package a;
import com.topjohnwu.magisk.utils.BootSigner;
import androidx.annotation.Keep;
@Keep
public class a extends BootSigner {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.MainActivity;
public class b extends MainActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.SplashActivity;
public class c extends SplashActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.AboutActivity;
public class d extends AboutActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.DonationActivity;
public class e extends DonationActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.FlashActivity;
public class f extends FlashActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.BootReceiver;
public class h extends BootReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.PackageReceiver;
public class i extends PackageReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
public class j extends ManagerUpdate {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.RebootReceiver;
public class k extends RebootReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
public class l extends ShortcutReceiver {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.services.OnBootService;
public class m extends OnBootService {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.services.UpdateCheckService;
public class n extends UpdateCheckService {
/* stub */
}

View File

@@ -0,0 +1,22 @@
package a;
import android.content.Context;
import android.util.AttributeSet;
import com.topjohnwu.magisk.components.AboutCardRow;
public class o extends AboutCardRow {
/* stub */
public o(Context context) {
super(context);
}
public o(Context context, AttributeSet attrs) {
super(context, attrs);
}
public o(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.SuRequestActivity;
public class p extends SuRequestActivity {
/* stub */
}

View File

@@ -0,0 +1,7 @@
package a;
import com.topjohnwu.magisk.MagiskManager;
public class q extends MagiskManager {
/* stub */
}

View File

@@ -2,9 +2,6 @@ package com.topjohnwu.magisk;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
@@ -15,18 +12,19 @@ import com.topjohnwu.magisk.utils.Utils;
import java.util.Locale; import java.util.Locale;
import butterknife.BindView; import androidx.annotation.Nullable;
import butterknife.ButterKnife; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
public class AboutActivity extends BaseActivity { public class AboutActivity extends BaseActivity {
@BindView(R.id.toolbar) Toolbar toolbar; Toolbar toolbar;
@BindView(R.id.app_version_info) AboutCardRow appVersionInfo; AboutCardRow appVersionInfo;
@BindView(R.id.app_changelog) AboutCardRow appChangelog; AboutCardRow appChangelog;
@BindView(R.id.app_translators) AboutCardRow appTranslators; AboutCardRow appTranslators;
@BindView(R.id.app_source_code) AboutCardRow appSourceCode; AboutCardRow appSourceCode;
@BindView(R.id.support_thread) AboutCardRow supportThread; AboutCardRow supportThread;
@BindView(R.id.follow_twitter) AboutCardRow twitter; AboutCardRow twitter;
@Override @Override
public int getDarkTheme() { public int getDarkTheme() {
@@ -37,7 +35,7 @@ public class AboutActivity extends BaseActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about); setContentView(R.layout.activity_about);
ButterKnife.bind(this); ViewBinder.bind(this);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish()); toolbar.setNavigationOnClickListener(view -> finish());

View File

@@ -57,6 +57,7 @@ public class Const {
public static final int REMOVE_LEGACY_LINK = 1630; public static final int REMOVE_LEGACY_LINK = 1630;
public static final int SEPOL_REFACTOR = 1640; public static final int SEPOL_REFACTOR = 1640;
public static final int FIX_ENV = 1650; public static final int FIX_ENV = 1650;
public static final int DBVER_SIX = 17000;
} }
public static class ID { public static class ID {
@@ -140,9 +141,6 @@ public class Const {
public static final int NAMESPACE_MODE_ISOLATE = 2; public static final int NAMESPACE_MODE_ISOLATE = 2;
public static final int NO_NOTIFICATION = 0; public static final int NO_NOTIFICATION = 0;
public static final int NOTIFICATION_TOAST = 1; public static final int NOTIFICATION_TOAST = 1;
public static final int NOTIFY_NORMAL_LOG = 0;
public static final int NOTIFY_USER_TOASTS = 1;
public static final int NOTIFY_USER_TO_OWNER = 2;
public static final int SU_PROMPT = 0; public static final int SU_PROMPT = 0;
public static final int SU_AUTO_DENY = 1; public static final int SU_AUTO_DENY = 1;
public static final int SU_AUTO_ALLOW = 2; public static final int SU_AUTO_ALLOW = 2;

View File

@@ -5,6 +5,14 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Xml; import android.util.Xml;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.receivers.BootReceiver;
import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.receivers.PackageReceiver;
import com.topjohnwu.magisk.receivers.RebootReceiver;
import com.topjohnwu.magisk.receivers.ShortcutReceiver;
import com.topjohnwu.magisk.services.OnBootService;
import com.topjohnwu.magisk.services.UpdateCheckService;
import com.topjohnwu.magisk.utils.FingerprintHelper; import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
@@ -18,11 +26,14 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class Data { public class Data {
// Global app instance // Global app instance
public static WeakReference<MagiskManager> weakApp; public static WeakReference<MagiskManager> weakApp;
public static Handler mainHandler = new Handler(Looper.getMainLooper()); public static Handler mainHandler = new Handler(Looper.getMainLooper());
public static Map<Class, Class> classMap = new HashMap<>();
// Current status // Current status
public static String magiskVersionString; public static String magiskVersionString;
@@ -60,6 +71,26 @@ public class Data {
public static int updateChannel; public static int updateChannel;
public static int repoOrder; public static int repoOrder;
static {
classMap.put(MagiskManager.class, a.q.class);
classMap.put(MainActivity.class, a.b.class);
classMap.put(SplashActivity.class, a.c.class);
classMap.put(AboutActivity.class, a.d.class);
classMap.put(DonationActivity.class, a.e.class);
classMap.put(FlashActivity.class, a.f.class);
classMap.put(NoUIActivity.class, a.g.class);
classMap.put(BootReceiver.class, a.h.class);
classMap.put(PackageReceiver.class, a.i.class);
classMap.put(ManagerUpdate.class, a.j.class);
classMap.put(RebootReceiver.class, a.k.class);
classMap.put(ShortcutReceiver.class, a.l.class);
classMap.put(OnBootService.class, a.m.class);
classMap.put(UpdateCheckService.class, a.n.class);
classMap.put(AboutCardRow.class, a.o.class);
classMap.put(SuRequestActivity.class, a.p.class);
}
public static void loadMagiskInfo() { public static void loadMagiskInfo() {
try { try {
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0]; magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];

View File

@@ -2,22 +2,20 @@ package com.topjohnwu.magisk;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import com.topjohnwu.magisk.components.AboutCardRow; import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.components.BaseActivity; import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import butterknife.BindView; import androidx.annotation.Nullable;
import butterknife.ButterKnife; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
public class DonationActivity extends BaseActivity { public class DonationActivity extends BaseActivity {
@BindView(R.id.toolbar) Toolbar toolbar; Toolbar toolbar;
@BindView(R.id.paypal) AboutCardRow paypal; AboutCardRow paypal;
@BindView(R.id.patreon) AboutCardRow patreon; AboutCardRow patreon;
@Override @Override
public int getDarkTheme() { public int getDarkTheme() {
@@ -28,7 +26,7 @@ public class DonationActivity extends BaseActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_donation); setContentView(R.layout.activity_donation);
ButterKnife.bind(this); ViewBinder.bind(this);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(view -> finish()); toolbar.setNavigationOnClickListener(view -> finish());

View File

@@ -4,8 +4,6 @@ import android.Manifest;
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.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
@@ -31,31 +29,27 @@ import java.util.Calendar;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import butterknife.BindView; import androidx.appcompat.app.ActionBar;
import butterknife.ButterKnife; import androidx.appcompat.widget.Toolbar;
import butterknife.OnClick;
public class FlashActivity extends BaseActivity { public class FlashActivity extends BaseActivity {
@BindView(R.id.toolbar) Toolbar toolbar; Toolbar toolbar;
@BindView(R.id.txtLog) TextView flashLogs; TextView flashLogs;
@BindView(R.id.button_panel) public LinearLayout buttonPanel; public LinearLayout buttonPanel;
@BindView(R.id.reboot) public Button reboot; public Button reboot;
@BindView(R.id.scrollView) ScrollView sv; ScrollView sv;
private List<String> logs; private List<String> logs;
@OnClick(R.id.no_thanks)
void dismiss() { void dismiss() {
finish(); finish();
} }
@OnClick(R.id.reboot)
void reboot() { void reboot() {
Shell.su("/system/bin/reboot").submit(); Shell.su("/system/bin/reboot").submit();
} }
@OnClick(R.id.save_logs)
void saveLogs() { void saveLogs() {
runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, () -> { runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, () -> {
Calendar now = Calendar.getInstance(); Calendar now = Calendar.getInstance();
@@ -88,7 +82,7 @@ public class FlashActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash); setContentView(R.layout.activity_flash);
ButterKnife.bind(this); ViewBinder.bind(this);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar(); ActionBar ab = getSupportActionBar();
if (ab != null) { if (ab != null) {
@@ -139,8 +133,9 @@ public class FlashActivity extends BaseActivity {
new InstallMagisk(this, console, logs, InstallMagisk.SECOND_SLOT_MODE).exec(); new InstallMagisk(this, console, logs, InstallMagisk.SECOND_SLOT_MODE).exec();
break; break;
case Const.Value.PATCH_BOOT: case Const.Value.PATCH_BOOT:
new InstallMagisk(this, console, logs, runWithPermission(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec(); () -> new InstallMagisk(this, console, logs,
intent.getParcelableExtra(Const.Key.FLASH_SET_BOOT)).exec());
break; break;
} }
} }

View File

@@ -3,17 +3,11 @@ package com.topjohnwu.magisk;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import com.google.android.material.navigation.NavigationView;
import com.topjohnwu.magisk.components.BaseActivity; import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.fragments.LogFragment; import com.topjohnwu.magisk.fragments.LogFragment;
import com.topjohnwu.magisk.fragments.MagiskFragment; import com.topjohnwu.magisk.fragments.MagiskFragment;
@@ -26,8 +20,12 @@ import com.topjohnwu.magisk.utils.Download;
import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import butterknife.BindView; import androidx.annotation.NonNull;
import butterknife.ButterKnife; import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends BaseActivity public class MainActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber { implements NavigationView.OnNavigationItemSelectedListener, Topic.Subscriber {
@@ -36,9 +34,9 @@ public class MainActivity extends BaseActivity
private int mDrawerItem; private int mDrawerItem;
private static boolean fromShortcut = false; private static boolean fromShortcut = false;
@BindView(R.id.drawer_layout) DrawerLayout drawer; public Toolbar toolbar;
@BindView(R.id.toolbar) public Toolbar toolbar; DrawerLayout drawer;
@BindView(R.id.nav_view) public NavigationView navigationView; NavigationView navigationView;
private float toolbarElevation; private float toolbarElevation;
@@ -50,13 +48,13 @@ public class MainActivity extends BaseActivity
@Override @Override
protected void onCreate(final Bundle savedInstanceState) { protected void onCreate(final Bundle savedInstanceState) {
if (!mm.hasInit) { if (!mm.hasInit) {
startActivity(new Intent(this, SplashActivity.class)); startActivity(new Intent(this, Data.classMap.get(SplashActivity.class)));
finish(); finish();
} }
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
ButterKnife.bind(this); ViewBinder.bind(this);
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
@@ -112,11 +110,6 @@ public class MainActivity extends BaseActivity
return true; return true;
} }
@Override
public int[] getSubscribedTopics() {
return new int[] {Topic.RELOAD_ACTIVITY};
}
@Override @Override
public void onPublish(int topic, Object[] result) { public void onPublish(int topic, Object[] result) {
recreate(); recreate();
@@ -196,11 +189,11 @@ public class MainActivity extends BaseActivity
displayFragment(new SettingsFragment(), true); displayFragment(new SettingsFragment(), true);
break; break;
case R.id.app_about: case R.id.app_about:
startActivity(new Intent(this, AboutActivity.class)); startActivity(new Intent(this, Data.classMap.get(AboutActivity.class)));
mDrawerItem = bak; mDrawerItem = bak;
break; break;
case R.id.donation: case R.id.donation:
startActivity(new Intent(this, DonationActivity.class)); startActivity(new Intent(this, Data.classMap.get(DonationActivity.class)));
mDrawerItem = bak; mDrawerItem = bak;
break; break;
} }

View File

@@ -1,9 +1,9 @@
package com.topjohnwu.magisk; package com.topjohnwu.magisk;
import android.support.annotation.NonNull;
import com.topjohnwu.magisk.components.BaseActivity; import com.topjohnwu.magisk.components.BaseActivity;
import androidx.annotation.NonNull;
public class NoUIActivity extends BaseActivity { public class NoUIActivity extends BaseActivity {
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

View File

@@ -44,7 +44,7 @@ public class SplashActivity extends BaseActivity {
} }
// Setup shortcuts // Setup shortcuts
sendBroadcast(new Intent(this, ShortcutReceiver.class)); sendBroadcast(new Intent(this, Data.classMap.get(ShortcutReceiver.class)));
if (Download.checkNetworkStatus(this)) { if (Download.checkNetworkStatus(this)) {
// Fire update check // Fire update check
@@ -58,7 +58,7 @@ public class SplashActivity extends BaseActivity {
mm.hasInit = true; mm.hasInit = true;
Intent intent = new Intent(this, MainActivity.class); Intent intent = new Intent(this, Data.classMap.get(MainActivity.class));
intent.putExtra(Const.Key.OPEN_SECTION, getIntent().getStringExtra(Const.Key.OPEN_SECTION)); intent.putExtra(Const.Key.OPEN_SECTION, getIntent().getStringExtra(Const.Key.OPEN_SECTION));
intent.putExtra(BaseActivity.INTENT_PERM, getIntent().getStringExtra(BaseActivity.INTENT_PERM)); intent.putExtra(BaseActivity.INTENT_PERM, getIntent().getStringExtra(BaseActivity.INTENT_PERM));
startActivity(intent); startActivity(intent);

View File

@@ -0,0 +1,258 @@
package com.topjohnwu.magisk;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.FileObserver;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import com.topjohnwu.magisk.utils.SuConnector;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import androidx.annotation.Nullable;
public class SuRequestActivity extends BaseActivity {
LinearLayout suPopup;
Spinner timeout;
ImageView appIcon;
TextView appNameView;
TextView packageNameView;
Button grant_btn;
Button deny_btn;
ImageView fingerprintImg;
TextView warning;
private SuConnector connector;
private Policy policy;
private CountDownTimer timer;
private FingerprintHelper fingerprintHelper;
class SuConnectorV1 extends SuConnector {
SuConnectorV1(String name) throws IOException {
socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.FILESYSTEM));
new FileObserver(name) {
@Override
public void onEvent(int fileEvent, String path) {
if (fileEvent == FileObserver.DELETE_SELF) {
finish();
}
}
}.startWatching();
}
@Override
public void response() {
try (OutputStream out = getOutputStream()) {
out.write((policy.policy == Policy.ALLOW ? "socket:ALLOW" : "socket:DENY").getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
class SuConnectorV2 extends SuConnector {
SuConnectorV2(String name) throws IOException {
socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT));
}
@Override
public void response() {
try (DataOutputStream out = getOutputStream()) {
out.writeInt(policy.policy);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public int getDarkTheme() {
return R.style.SuRequest_Dark;
}
@Override
public void finish() {
if (timer != null)
timer.cancel();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
super.finish();
}
@Override
public void onBackPressed() {
if (policy != null) {
handleAction(Policy.DENY);
} else {
finish();
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
PackageManager pm = getPackageManager();
mm.mDB.clearOutdated();
// Get policy
Intent intent = getIntent();
try {
connector = intent.getIntExtra("version", 1) == 1 ?
new SuConnectorV1(intent.getStringExtra("socket")) :
new SuConnectorV2(intent.getStringExtra("socket"));
Bundle bundle = connector.readSocketInput();
int uid = Integer.parseInt(bundle.getString("uid"));
policy = mm.mDB.getPolicy(uid);
if (policy == null) {
policy = new Policy(uid, pm);
}
} catch (IOException | PackageManager.NameNotFoundException e) {
e.printStackTrace();
finish();
return;
}
// Never allow com.topjohnwu.magisk (could be malware)
if (TextUtils.equals(policy.packageName, Const.ORIG_PKG_NAME)) {
finish();
return;
}
switch (Data.suResponseType) {
case Const.Value.SU_AUTO_DENY:
handleAction(Policy.DENY, 0);
return;
case Const.Value.SU_AUTO_ALLOW:
handleAction(Policy.ALLOW, 0);
return;
case Const.Value.SU_PROMPT:
default:
}
// If not interactive, response directly
if (policy.policy != Policy.INTERACTIVE) {
handleAction();
return;
}
setContentView(R.layout.activity_request);
ViewBinder.bind(this);
appIcon.setImageDrawable(policy.info.loadIcon(pm));
appNameView.setText(policy.appName);
packageNameView.setText(policy.packageName);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.allow_timeout, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
timeout.setAdapter(adapter);
timer = new CountDownTimer(Data.suRequestTimeout * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
deny_btn.setText(getString(R.string.deny_with_str, "(" + millisUntilFinished / 1000 + ")"));
}
@Override
public void onFinish() {
deny_btn.setText(getString(R.string.deny_with_str, "(0)"));
handleAction(Policy.DENY);
}
};
boolean useFingerprint = Data.suFingerprint && FingerprintHelper.canUseFingerprint();
if (useFingerprint) {
try {
fingerprintHelper = new FingerprintHelper() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
warning.setText(errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
warning.setText(helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
handleAction(Policy.ALLOW);
}
@Override
public void onAuthenticationFailed() {
warning.setText(R.string.auth_fail);
}
};
fingerprintHelper.authenticate();
} catch (Exception e) {
e.printStackTrace();
useFingerprint = false;
}
}
if (!useFingerprint) {
grant_btn.setOnClickListener(v -> {
handleAction(Policy.ALLOW);
timer.cancel();
});
grant_btn.requestFocus();
}
grant_btn.setVisibility(useFingerprint ? View.GONE : View.VISIBLE);
fingerprintImg.setVisibility(useFingerprint ? View.VISIBLE : View.GONE);
deny_btn.setOnClickListener(v -> {
handleAction(Policy.DENY);
timer.cancel();
});
suPopup.setOnClickListener(v -> cancelTimeout());
timeout.setOnTouchListener((v, event) -> cancelTimeout());
timer.start();
}
private boolean cancelTimeout() {
timer.cancel();
deny_btn.setText(getString(R.string.deny));
return false;
}
private void handleAction() {
connector.response();
finish();
}
private void handleAction(int action) {
handleAction(action, Const.Value.timeoutList[timeout.getSelectedItemPosition()]);
}
private void handleAction(int action, int time) {
policy.policy = action;
if (time >= 0) {
policy.until = (time == 0) ? 0 : (System.currentTimeMillis() / 1000 + time * 60);
mm.mDB.addPolicy(policy);
}
handleAction();
}
}

View File

@@ -0,0 +1,293 @@
package com.topjohnwu.magisk;
import android.content.Context;
import android.view.View;
import com.topjohnwu.magisk.adapters.ApplicationAdapter;
import com.topjohnwu.magisk.adapters.ModulesAdapter;
import com.topjohnwu.magisk.adapters.PolicyAdapter;
import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.adapters.SuLogAdapter;
import com.topjohnwu.magisk.components.AboutCardRow;
import com.topjohnwu.magisk.components.CustomAlertDialog;
import com.topjohnwu.magisk.fragments.LogFragment;
import com.topjohnwu.magisk.fragments.MagiskFragment;
import com.topjohnwu.magisk.fragments.MagiskHideFragment;
import com.topjohnwu.magisk.fragments.MagiskLogFragment;
import com.topjohnwu.magisk.fragments.ModulesFragment;
import com.topjohnwu.magisk.fragments.ReposFragment;
import com.topjohnwu.magisk.fragments.SuLogFragment;
import com.topjohnwu.magisk.fragments.SuperuserFragment;
import androidx.core.content.ContextCompat;
public class ViewBinder {
public static void bind(MainActivity target) {
target.drawer = target.findViewById(R.id.drawer_layout);
target.toolbar = target.findViewById(R.id.toolbar);
target.navigationView = target.findViewById(R.id.nav_view);
}
public static void bind(AboutActivity target) {
target.toolbar = target.findViewById(R.id.toolbar);
target.appVersionInfo = target.findViewById(R.id.app_version_info);
target.appChangelog = target.findViewById(R.id.app_changelog);
target.appTranslators = target.findViewById(R.id.app_translators);
target.appSourceCode = target.findViewById(R.id.app_source_code);
target.supportThread = target.findViewById(R.id.support_thread);
target.twitter = target.findViewById(R.id.follow_twitter);
}
public static void bind(DonationActivity target) {
target.toolbar = target.findViewById(R.id.toolbar);
target.paypal = target.findViewById(R.id.paypal);
target.patreon = target.findViewById(R.id.patreon);
}
public static void bind(FlashActivity target) {
target.toolbar = target.findViewById(R.id.toolbar);
target.flashLogs = target.findViewById(R.id.txtLog);
target.buttonPanel = target.findViewById(R.id.button_panel);
target.sv = target.findViewById(R.id.scrollView);
target.reboot = target.findViewById(R.id.reboot);
target.reboot.setOnClickListener(v -> target.reboot());
target.findViewById(R.id.no_thanks).setOnClickListener(v -> target.finish());
target.findViewById(R.id.save_logs).setOnClickListener(v -> target.saveLogs());
}
public static void bind(SuRequestActivity target) {
target.suPopup = target.findViewById(R.id.su_popup);
target.timeout = target.findViewById(R.id.timeout);
target.appIcon = target.findViewById(R.id.app_icon);
target.appNameView = target.findViewById(R.id.app_name);
target.packageNameView = target.findViewById(R.id.package_name);
target.grant_btn = target.findViewById(R.id.grant_btn);
target.deny_btn = target.findViewById(R.id.deny_btn);
target.fingerprintImg = target.findViewById(R.id.fingerprint);
target.warning = target.findViewById(R.id.warning);
}
public static void bind(LogFragment target, View v) {
target.viewPager = v.findViewById(R.id.container);
target.tab = v.findViewById(R.id.tab);
}
public static void unbind(LogFragment target) {
target.viewPager = null;
target.tab = null;
}
public static void bind(MagiskFragment target, View v) {
target.mSwipeRefreshLayout = v.findViewById(R.id.swipeRefreshLayout);
target.coreOnlyNotice = v.findViewById(R.id.core_only_notice);
target.magiskUpdate = v.findViewById(R.id.magisk_update);
target.magiskUpdateIcon = v.findViewById(R.id.magisk_update_icon);
target.magiskUpdateText = v.findViewById(R.id.magisk_update_status);
target.magiskUpdateProgress = v.findViewById(R.id.magisk_update_progress);
target.magiskStatusIcon = v.findViewById(R.id.magisk_status_icon);
target.magiskVersionText = v.findViewById(R.id.magisk_version);
target.safetyNetCard = v.findViewById(R.id.safetyNet_card);
target.safetyNetRefreshIcon = v.findViewById(R.id.safetyNet_refresh);
target.safetyNetStatusText = v.findViewById(R.id.safetyNet_status);
target.safetyNetProgress = v.findViewById(R.id.safetyNet_check_progress);
target.expandLayout = v.findViewById(R.id.expand_layout);
target.ctsStatusIcon = v.findViewById(R.id.cts_status_icon);
target.ctsStatusText = v.findViewById(R.id.cts_status);
target.basicStatusIcon = v.findViewById(R.id.basic_status_icon);
target.basicStatusText = v.findViewById(R.id.basic_status);
target.installOptionCard = v.findViewById(R.id.install_option_card);
target.keepEncChkbox = v.findViewById(R.id.keep_force_enc);
target.keepVerityChkbox = v.findViewById(R.id.keep_verity);
target.installButton = v.findViewById(R.id.install_button);
target.installText = v.findViewById(R.id.install_text);
target.uninstallButton = v.findViewById(R.id.uninstall_button);
v.findViewById(R.id.safetyNet_title).setOnClickListener(v1 -> target.safetyNet());
v.findViewById(R.id.install_button).setOnClickListener(v1 -> target.install());
v.findViewById(R.id.uninstall_button).setOnClickListener(v1 -> target.uninstall());
Context ctx = target.getContext();
target.colorBad = ContextCompat.getColor(ctx, R.color.red500);
target.colorOK = ContextCompat.getColor(ctx, R.color.green500);
target.colorWarn = ContextCompat.getColor(ctx, R.color.yellow500);
target.colorNeutral = ContextCompat.getColor(ctx, R.color.grey500);
target.colorInfo = ContextCompat.getColor(ctx, R.color.blue500);
}
public static void unbind(MagiskFragment target) {
target.mSwipeRefreshLayout = null;
target.coreOnlyNotice = null;
target.magiskUpdate = null;
target.magiskUpdateIcon = null;
target.magiskUpdateText = null;
target.magiskUpdateProgress = null;
target.magiskStatusIcon = null;
target.magiskVersionText = null;
target.safetyNetCard = null;
target.safetyNetRefreshIcon = null;
target.safetyNetStatusText = null;
target.safetyNetProgress = null;
target.expandLayout = null;
target.ctsStatusIcon = null;
target.ctsStatusText = null;
target.basicStatusIcon = null;
target.basicStatusText = null;
target.installOptionCard = null;
target.keepEncChkbox = null;
target.keepVerityChkbox = null;
target.installButton = null;
target.installText = null;
target.uninstallButton = null;
View v = target.getView();
v.findViewById(R.id.safetyNet_title).setOnClickListener(null);
v.findViewById(R.id.install_button).setOnClickListener(null);
v.findViewById(R.id.uninstall_button).setOnClickListener(null);
}
public static void bind(MagiskHideFragment target, View v) {
target.mSwipeRefreshLayout = v.findViewById(R.id.swipeRefreshLayout);
target.recyclerView = v.findViewById(R.id.recyclerView);
}
public static void unbind(MagiskHideFragment target) {
target.mSwipeRefreshLayout = null;
target.recyclerView = null;
}
public static void bind(MagiskLogFragment target, View v) {
target.txtLog = v.findViewById(R.id.txtLog);
target.svLog = v.findViewById(R.id.svLog);
target.hsvLog = v.findViewById(R.id.hsvLog);
target.progressBar = v.findViewById(R.id.progressBar);
}
public static void unbind(MagiskLogFragment target) {
target.txtLog = null;
target.svLog = null;
target.hsvLog = null;
target.progressBar = null;
}
public static void bind(ModulesFragment target, View v) {
target.mSwipeRefreshLayout = v.findViewById(R.id.swipeRefreshLayout);
target.recyclerView = v.findViewById(R.id.recyclerView);
target.emptyRv = v.findViewById(R.id.empty_rv);
v.findViewById(R.id.fab).setOnClickListener(v1 -> target.selectFile());
}
public static void unbind(ModulesFragment target) {
target.mSwipeRefreshLayout = null;
target.recyclerView = null;
target.emptyRv = null;
View v = target.getView();
v.findViewById(R.id.fab).setOnClickListener(null);
}
public static void bind(ReposFragment target, View source) {
target.recyclerView = source.findViewById(R.id.recyclerView);
target.emptyRv = source.findViewById(R.id.empty_rv);
target.mSwipeRefreshLayout = source.findViewById(R.id.swipeRefreshLayout);
}
public static void unbind(ReposFragment target) {
target.recyclerView = null;
target.emptyRv = null;
target.mSwipeRefreshLayout = null;
}
public static void bind(SuLogFragment target, View source) {
target.emptyRv = source.findViewById(R.id.empty_rv);
target.recyclerView = source.findViewById(R.id.recyclerView);
}
public static void unbind(SuLogFragment target) {
target.emptyRv = null;
target.recyclerView = null;
}
public static void bind(SuperuserFragment target, View source) {
target.recyclerView = source.findViewById(R.id.recyclerView);
target.emptyRv = source.findViewById(R.id.empty_rv);
}
public static void unbind(SuperuserFragment target) {
target.emptyRv = null;
target.recyclerView = null;
}
public static void bind(CustomAlertDialog.ViewHolder target, View source) {
target.dialogLayout = source.findViewById(R.id.dialog_layout);
target.buttons = source.findViewById(R.id.button_panel);
target.messageView = source.findViewById(R.id.message);
target.negative = source.findViewById(R.id.negative);
target.positive = source.findViewById(R.id.positive);
target.neutral = source.findViewById(R.id.neutral);
}
public static void bind(AboutCardRow target, View source) {
target.mTitle = source.findViewById(android.R.id.title);
target.mSummary = source.findViewById(android.R.id.summary);
target.mIcon = source.findViewById(android.R.id.icon);
target.mView = source.findViewById(R.id.container);
}
public static void bind(ApplicationAdapter.ViewHolder target, View source) {
target.appIcon = source.findViewById(R.id.app_icon);
target.appName = source.findViewById(R.id.app_name);
target.appPackage = source.findViewById(R.id.package_name);
target.checkBox = source.findViewById(R.id.checkbox);
}
public static void bind(ModulesAdapter.ViewHolder target, View source) {
target.title = source.findViewById(R.id.title);
target.versionName = source.findViewById(R.id.version_name);
target.description = source.findViewById(R.id.description);
target.notice = source.findViewById(R.id.notice);
target.checkBox = source.findViewById(R.id.checkbox);
target.author = source.findViewById(R.id.author);
target.delete = source.findViewById(R.id.delete);
}
public static void bind(PolicyAdapter.ViewHolder target, View source) {
target.appName = source.findViewById(R.id.app_name);
target.packageName = source.findViewById(R.id.package_name);
target.appIcon = source.findViewById(R.id.app_icon);
target.masterSwitch = source.findViewById(R.id.master_switch);
target.notificationSwitch = source.findViewById(R.id.notification_switch);
target.loggingSwitch = source.findViewById(R.id.logging_switch);
target.expandLayout = source.findViewById(R.id.expand_layout);
target.delete = source.findViewById(R.id.delete);
target.moreInfo = source.findViewById(R.id.more_info);
}
public static void bind(ReposAdapter.SectionHolder target, View source) {
target.sectionText = source.findViewById(R.id.section_text);
}
public static void bind(ReposAdapter.RepoHolder target, View source) {
target.title = source.findViewById(R.id.title);
target.versionName = source.findViewById(R.id.version_name);
target.description = source.findViewById(R.id.description);
target.author = source.findViewById(R.id.author);
target.infoLayout = source.findViewById(R.id.info_layout);
target.downloadImage = source.findViewById(R.id.download);
target.updateTime = source.findViewById(R.id.update_time);
}
public static void bind(SuLogAdapter.SectionHolder target, View source) {
target.date = source.findViewById(R.id.date);
target.arrow = source.findViewById(R.id.arrow);
}
public static void bind(SuLogAdapter.LogViewHolder target, View source) {
target.appName = source.findViewById(R.id.app_name);
target.action = source.findViewById(R.id.action);
target.time = source.findViewById(R.id.time);
target.fromPid = source.findViewById(R.id.fromPid);
target.toUid = source.findViewById(R.id.toUid);
target.command = source.findViewById(R.id.command);
target.expandLayout = source.findViewById(R.id.expand_layout);
}
}

View File

@@ -6,8 +6,6 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -19,6 +17,7 @@ import android.widget.TextView;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.utils.LocaleManager; import com.topjohnwu.magisk.utils.LocaleManager;
import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
@@ -28,8 +27,8 @@ import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import butterknife.BindView; import androidx.annotation.NonNull;
import butterknife.ButterKnife; import androidx.recyclerview.widget.RecyclerView;
public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> { public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.ViewHolder> {
@@ -123,16 +122,16 @@ public class ApplicationAdapter extends RecyclerView.Adapter<ApplicationAdapter.
AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps); AsyncTask.THREAD_POOL_EXECUTOR.execute(this::loadApps);
} }
static class ViewHolder extends RecyclerView.ViewHolder { public static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.app_icon) ImageView appIcon; public ImageView appIcon;
@BindView(R.id.app_name) TextView appName; public TextView appName;
@BindView(R.id.package_name) TextView appPackage; public TextView appPackage;
@BindView(R.id.checkbox) CheckBox checkBox; public CheckBox checkBox;
ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
} }
} }

View File

@@ -1,8 +1,6 @@
package com.topjohnwu.magisk.adapters; package com.topjohnwu.magisk.adapters;
import android.content.Context; import android.content.Context;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -11,15 +9,16 @@ import android.widget.CheckBox;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.SnackbarMaker; import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.container.Module; import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import java.util.List; import java.util.List;
import butterknife.BindView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHolder> { public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHolder> {
@@ -46,9 +45,9 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
String noInfo = context.getString(R.string.no_info_provided); String noInfo = context.getString(R.string.no_info_provided);
holder.title.setText(module.getName()); holder.title.setText(module.getName());
holder.versionName.setText( TextUtils.isEmpty(version) ? noInfo : version); holder.versionName.setText(TextUtils.isEmpty(version) ? noInfo : version);
holder.author.setText( TextUtils.isEmpty(author) ? noInfo : context.getString(R.string.author, author)); holder.author.setText(TextUtils.isEmpty(author) ? noInfo : context.getString(R.string.author, author));
holder.description.setText( TextUtils.isEmpty(description) ? noInfo : description); holder.description.setText(TextUtils.isEmpty(description) ? noInfo : description);
holder.checkBox.setOnCheckedChangeListener(null); holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setChecked(module.isEnabled()); holder.checkBox.setChecked(module.isEnabled());
@@ -102,19 +101,19 @@ public class ModulesAdapter extends RecyclerView.Adapter<ModulesAdapter.ViewHold
return mList.size(); return mList.size();
} }
static class ViewHolder extends RecyclerView.ViewHolder { public static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title) TextView title; public TextView title;
@BindView(R.id.version_name) TextView versionName; public TextView versionName;
@BindView(R.id.description) TextView description; public TextView description;
@BindView(R.id.notice) TextView notice; public TextView notice;
@BindView(R.id.checkbox) CheckBox checkBox; public CheckBox checkBox;
@BindView(R.id.author) TextView author; public TextView author;
@BindView(R.id.delete) ImageView delete; public ImageView delete;
ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
if (!Shell.rootAccess()) { if (!Shell.rootAccess()) {
checkBox.setEnabled(false); checkBox.setEnabled(false);

View File

@@ -2,8 +2,6 @@ package com.topjohnwu.magisk.adapters;
import android.app.Activity; import android.app.Activity;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -11,7 +9,9 @@ import android.widget.ImageView;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.CustomAlertDialog; import com.topjohnwu.magisk.components.CustomAlertDialog;
import com.topjohnwu.magisk.components.ExpandableView; import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.components.SnackbarMaker; import com.topjohnwu.magisk.components.SnackbarMaker;
@@ -22,8 +22,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import butterknife.BindView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder> { public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder> {
@@ -120,24 +119,24 @@ public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.ViewHolder
return policyList.size(); return policyList.size();
} }
static class ViewHolder extends RecyclerView.ViewHolder implements ExpandableView { public static class ViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
@BindView(R.id.app_name) TextView appName; public TextView appName;
@BindView(R.id.package_name) TextView packageName; public TextView packageName;
@BindView(R.id.app_icon) ImageView appIcon; public ImageView appIcon;
@BindView(R.id.master_switch) Switch masterSwitch; public Switch masterSwitch;
@BindView(R.id.notification_switch) Switch notificationSwitch; public Switch notificationSwitch;
@BindView(R.id.logging_switch) Switch loggingSwitch; public Switch loggingSwitch;
@BindView(R.id.expand_layout) ViewGroup expandLayout; public ViewGroup expandLayout;
@BindView(R.id.delete) ImageView delete; public ImageView delete;
@BindView(R.id.more_info) ImageView moreInfo; public ImageView moreInfo;
private Container container = new Container(); private Container container = new Container();
public ViewHolder(View itemView) { public ViewHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
container.expandLayout = expandLayout; container.expandLayout = expandLayout;
setupExpandable(); setupExpandable();
} }

View File

@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.adapters;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Pair; import android.util.Pair;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -13,6 +12,7 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.asyncs.MarkDownWindow; import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.asyncs.ProcessRepoZip; import com.topjohnwu.magisk.asyncs.ProcessRepoZip;
import com.topjohnwu.magisk.components.BaseActivity; import com.topjohnwu.magisk.components.BaseActivity;
@@ -25,8 +25,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import butterknife.BindView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, ReposAdapter.RepoHolder> { public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, ReposAdapter.RepoHolder> {
@@ -89,11 +88,16 @@ public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, R
Repo repo = repoPairs.get(section).second.get(position); Repo repo = repoPairs.get(section).second.get(position);
Context context = holder.itemView.getContext(); Context context = holder.itemView.getContext();
holder.title.setText(repo.getName()); String name = repo.getName();
holder.versionName.setText(repo.getVersion()); String version = repo.getVersion();
String author = repo.getAuthor(); String author = repo.getAuthor();
holder.author.setText(TextUtils.isEmpty(author) ? null : context.getString(R.string.author, author)); String description = repo.getDescription();
holder.description.setText(repo.getDescription()); String noInfo = context.getString(R.string.no_info_provided);
holder.title.setText(TextUtils.isEmpty(name) ? noInfo : name);
holder.versionName.setText(TextUtils.isEmpty(version) ? noInfo : version);
holder.author.setText(TextUtils.isEmpty(author) ? noInfo : context.getString(R.string.author, author));
holder.description.setText(TextUtils.isEmpty(description) ? noInfo : description);
holder.updateTime.setText(context.getString(R.string.updated_on, repo.getLastUpdateString())); holder.updateTime.setText(context.getString(R.string.updated_on, repo.getLastUpdateString()));
holder.infoLayout.setOnClickListener(v -> holder.infoLayout.setOnClickListener(v ->
@@ -159,29 +163,29 @@ public class ReposAdapter extends SectionedAdapter<ReposAdapter.SectionHolder, R
notifyDataSetChanged(); notifyDataSetChanged();
} }
static class SectionHolder extends RecyclerView.ViewHolder { public static class SectionHolder extends RecyclerView.ViewHolder {
@BindView(R.id.section_text) TextView sectionText; public TextView sectionText;
SectionHolder(View itemView) { SectionHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
} }
} }
static class RepoHolder extends RecyclerView.ViewHolder { public static class RepoHolder extends RecyclerView.ViewHolder {
@BindView(R.id.title) TextView title; public TextView title;
@BindView(R.id.version_name) TextView versionName; public TextView versionName;
@BindView(R.id.description) TextView description; public TextView description;
@BindView(R.id.author) TextView author; public TextView author;
@BindView(R.id.info_layout) LinearLayout infoLayout; public LinearLayout infoLayout;
@BindView(R.id.download) ImageView downloadImage; public ImageView downloadImage;
@BindView(R.id.update_time) TextView updateTime; public TextView updateTime;
RepoHolder(View itemView) { RepoHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
} }
} }

View File

@@ -1,8 +1,9 @@
package com.topjohnwu.magisk.adapters; package com.topjohnwu.magisk.adapters;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
public abstract class SectionedAdapter<S extends RecyclerView.ViewHolder, C extends RecyclerView.ViewHolder> public abstract class SectionedAdapter<S extends RecyclerView.ViewHolder, C extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<RecyclerView.ViewHolder> { extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

View File

@@ -1,7 +1,6 @@
package com.topjohnwu.magisk.adapters; package com.topjohnwu.magisk.adapters;
import android.database.Cursor; import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -11,6 +10,7 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.ExpandableView; import com.topjohnwu.magisk.components.ExpandableView;
import com.topjohnwu.magisk.container.SuLogEntry; import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.database.MagiskDatabaseHelper; import com.topjohnwu.magisk.database.MagiskDatabaseHelper;
@@ -20,8 +20,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import butterknife.BindView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, SuLogAdapter.LogViewHolder> { public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, SuLogAdapter.LogViewHolder> {
@@ -117,32 +116,32 @@ public class SuLogAdapter extends SectionedAdapter<SuLogAdapter.SectionHolder, S
notifyDataSetChanged(); notifyDataSetChanged();
} }
static class SectionHolder extends RecyclerView.ViewHolder { public static class SectionHolder extends RecyclerView.ViewHolder {
@BindView(R.id.date) TextView date; public TextView date;
@BindView(R.id.arrow) ImageView arrow; public ImageView arrow;
SectionHolder(View itemView) { SectionHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
} }
} }
static class LogViewHolder extends RecyclerView.ViewHolder implements ExpandableView { public static class LogViewHolder extends RecyclerView.ViewHolder implements ExpandableView {
@BindView(R.id.app_name) TextView appName; public TextView appName;
@BindView(R.id.action) TextView action; public TextView action;
@BindView(R.id.time) TextView time; public TextView time;
@BindView(R.id.fromPid) TextView fromPid; public TextView fromPid;
@BindView(R.id.toUid) TextView toUid; public TextView toUid;
@BindView(R.id.command) TextView command; public TextView command;
@BindView(R.id.expand_layout) ViewGroup expandLayout; public ViewGroup expandLayout;
private Container container = new Container(); private Container container = new Container();
LogViewHolder(View itemView) { LogViewHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); ViewBinder.bind(this, itemView);
container.expandLayout = expandLayout; container.expandLayout = expandLayout;
setupExpandable(); setupExpandable();
} }

View File

@@ -1,13 +1,13 @@
package com.topjohnwu.magisk.adapters; package com.topjohnwu.magisk.adapters;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
public class TabFragmentAdapter extends FragmentPagerAdapter { public class TabFragmentAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList; private List<Fragment> fragmentList;

View File

@@ -4,7 +4,6 @@ import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@@ -44,6 +43,8 @@ import java.net.HttpURLConnection;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
public class InstallMagisk extends ParallelTask<Void, Void, Boolean> { public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
private static final int PATCH_MODE = 0; private static final int PATCH_MODE = 0;

View File

@@ -1,7 +1,6 @@
package com.topjohnwu.magisk.asyncs; package com.topjohnwu.magisk.asyncs;
import android.app.Activity; import android.app.Activity;
import android.support.v7.app.AlertDialog;
import android.webkit.WebView; import android.webkit.WebView;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
@@ -18,6 +17,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import androidx.appcompat.app.AlertDialog;
public class MarkDownWindow extends ParallelTask<Void, Void, String> { public class MarkDownWindow extends ParallelTask<Void, Void, String> {
private String mTitle; private String mTitle;

View File

@@ -4,7 +4,6 @@ import android.Manifest;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull;
import android.widget.Toast; import android.widget.Toast;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
@@ -35,6 +34,8 @@ import java.util.jar.JarEntry;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import androidx.annotation.NonNull;
public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> { public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
private ProgressDialog progressDialog; private ProgressDialog progressDialog;
@@ -140,7 +141,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
if (result) { if (result) {
Uri uri = Uri.fromFile(mFile); Uri uri = Uri.fromFile(mFile);
if (mInstall) { if (mInstall) {
Intent intent = new Intent(activity, FlashActivity.class); Intent intent = new Intent(activity, Data.classMap.get(FlashActivity.class));
intent.setData(uri).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP); intent.setData(uri).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
activity.startActivity(intent); activity.startActivity(intent);
} else { } else {

View File

@@ -27,19 +27,17 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import butterknife.BindView;
import butterknife.ButterKnife;
/** /**
* @author dvdandroid * @author dvdandroid
*/ */
public class AboutCardRow extends LinearLayout { public class AboutCardRow extends LinearLayout {
@BindView(android.R.id.title) TextView mTitle; public TextView mTitle;
@BindView(android.R.id.summary) TextView mSummary; public TextView mSummary;
@BindView(android.R.id.icon) ImageView mIcon; public ImageView mIcon;
@BindView(R.id.container) View mView; public View mView;
public AboutCardRow(Context context) { public AboutCardRow(Context context) {
this(context, null); this(context, null);
@@ -52,7 +50,7 @@ public class AboutCardRow extends LinearLayout {
public AboutCardRow(Context context, AttributeSet attrs, int defStyleAttr) { public AboutCardRow(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.info_item_row, this); LayoutInflater.from(context).inflate(R.layout.info_item_row, this);
ButterKnife.bind(this, this); ViewBinder.bind(this, this);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AboutCardRow, 0, 0); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AboutCardRow, 0, 0);
String title; String title;
@@ -69,8 +67,6 @@ public class AboutCardRow extends LinearLayout {
@Override @Override
public void setOnClickListener(OnClickListener l) { public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
mView.setOnClickListener(l); mView.setOnClickListener(l);
} }

View File

@@ -1,12 +1,13 @@
package com.topjohnwu.magisk.components; package com.topjohnwu.magisk.components;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.Fragment;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MagiskManager; import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Topic;
import androidx.fragment.app.Fragment;
public class BaseFragment extends Fragment implements Topic.AutoSubscriber { public class BaseFragment extends Fragment implements Topic.AutoSubscriber {
public MagiskManager mm; public MagiskManager mm;

View File

@@ -2,11 +2,6 @@ package com.topjohnwu.magisk.components;
import android.app.Activity; import android.app.Activity;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.annotation.StyleRes;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
@@ -14,9 +9,13 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import butterknife.BindView; import androidx.annotation.NonNull;
import butterknife.ButterKnife; import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AlertDialog;
public class CustomAlertDialog extends AlertDialog.Builder { public class CustomAlertDialog extends AlertDialog.Builder {
@@ -28,16 +27,16 @@ public class CustomAlertDialog extends AlertDialog.Builder {
private ViewHolder vh; private ViewHolder vh;
public class ViewHolder { public class ViewHolder {
@BindView(R.id.dialog_layout) public LinearLayout dialogLayout; public LinearLayout dialogLayout;
@BindView(R.id.button_panel) public LinearLayout buttons; public LinearLayout buttons;
@BindView(R.id.message) public TextView messageView; public TextView messageView;
@BindView(R.id.negative) public Button negative; public Button negative;
@BindView(R.id.positive) public Button positive; public Button positive;
@BindView(R.id.neutral) public Button neutral; public Button neutral;
ViewHolder(View v) { ViewHolder(View v) {
ButterKnife.bind(this, v); ViewBinder.bind(this, v);
messageView.setVisibility(View.GONE); messageView.setVisibility(View.GONE);
negative.setVisibility(View.GONE); negative.setVisibility(View.GONE);
positive.setVisibility(View.GONE); positive.setVisibility(View.GONE);

View File

@@ -1,11 +1,12 @@
package com.topjohnwu.magisk.components; package com.topjohnwu.magisk.components;
import android.app.Activity; import android.app.Activity;
import android.support.annotation.NonNull;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.asyncs.InstallMagisk; import com.topjohnwu.magisk.asyncs.InstallMagisk;
import androidx.annotation.NonNull;
public class EnvFixDialog extends CustomAlertDialog { public class EnvFixDialog extends CustomAlertDialog {
public EnvFixDialog(@NonNull Activity activity) { public EnvFixDialog(@NonNull Activity activity) {

View File

@@ -4,9 +4,6 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.StyleRes;
import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager; import android.view.WindowManager;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
@@ -15,6 +12,10 @@ import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.LocaleManager; import com.topjohnwu.magisk.utils.LocaleManager;
import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Topic;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AppCompatActivity;
public abstract class FlavorActivity extends AppCompatActivity implements Topic.AutoSubscriber { public abstract class FlavorActivity extends AppCompatActivity implements Topic.AutoSubscriber {
private ActivityResultListener activityResultListener; private ActivityResultListener activityResultListener;
@@ -42,11 +43,11 @@ public abstract class FlavorActivity extends AppCompatActivity implements Topic.
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Topic.subscribe(this); Topic.subscribe(this);
if (Data.isDarkTheme && getDarkTheme() != -1) { if (Data.isDarkTheme && getDarkTheme() != -1) {
setTheme(getDarkTheme()); setTheme(getDarkTheme());
} }
super.onCreate(savedInstanceState);
} }
@Override @Override

View File

@@ -3,10 +3,9 @@ package com.topjohnwu.magisk.components;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.widget.Toast; import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.FlashActivity; import com.topjohnwu.magisk.FlashActivity;
@@ -17,6 +16,8 @@ import com.topjohnwu.magisk.utils.Utils;
import java.util.List; import java.util.List;
import androidx.appcompat.app.AlertDialog;
class InstallMethodDialog extends AlertDialog.Builder { class InstallMethodDialog extends AlertDialog.Builder {
InstallMethodDialog(BaseActivity activity, List<String> options) { InstallMethodDialog(BaseActivity activity, List<String> options) {
@@ -37,7 +38,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
(requestCode, resultCode, data) -> { (requestCode, resultCode, data) -> {
if (requestCode == Const.ID.SELECT_BOOT && if (requestCode == Const.ID.SELECT_BOOT &&
resultCode == BaseActivity.RESULT_OK && data != null) { resultCode == BaseActivity.RESULT_OK && data != null) {
Intent i = new Intent(activity, FlashActivity.class) Intent i = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_SET_BOOT, data.getData()) .putExtra(Const.Key.FLASH_SET_BOOT, data.getData())
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_BOOT); .putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_BOOT);
activity.startActivity(i); activity.startActivity(i);
@@ -55,7 +56,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
}, Data.magiskLink, filename); }, Data.magiskLink, filename);
break; break;
case 2: case 2:
intent = new Intent(activity, FlashActivity.class) intent = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_MAGISK); .putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_MAGISK);
activity.startActivity(intent); activity.startActivity(intent);
break; break;
@@ -65,7 +66,7 @@ class InstallMethodDialog extends AlertDialog.Builder {
.setMessage(R.string.install_inactive_slot_msg) .setMessage(R.string.install_inactive_slot_msg)
.setCancelable(true) .setCancelable(true)
.setPositiveButton(R.string.yes, (d, i) -> { .setPositiveButton(R.string.yes, (d, i) -> {
Intent it = new Intent(activity, FlashActivity.class) Intent it = new Intent(activity, Data.classMap.get(FlashActivity.class))
.putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_INACTIVE_SLOT); .putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_INACTIVE_SLOT);
activity.startActivity(it); activity.startActivity(it);
}) })

View File

@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.components;
import android.Manifest; import android.Manifest;
import android.content.Intent; import android.content.Intent;
import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
@@ -13,6 +12,8 @@ import com.topjohnwu.magisk.asyncs.MarkDownWindow;
import com.topjohnwu.magisk.receivers.ManagerUpdate; import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import androidx.annotation.NonNull;
public class ManagerInstallDialog extends CustomAlertDialog { public class ManagerInstallDialog extends CustomAlertDialog {
public ManagerInstallDialog(@NonNull BaseActivity activity) { public ManagerInstallDialog(@NonNull BaseActivity activity) {
@@ -25,7 +26,7 @@ public class ManagerInstallDialog extends CustomAlertDialog {
setCancelable(true); setCancelable(true);
setPositiveButton(R.string.install, (d, i) -> activity.runWithPermission( setPositiveButton(R.string.install, (d, i) -> activity.runWithPermission(
new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> { new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, () -> {
Intent intent = new Intent(mm, ManagerUpdate.class); Intent intent = new Intent(mm, Data.classMap.get(ManagerUpdate.class));
intent.putExtra(Const.Key.INTENT_SET_LINK, Data.managerLink); intent.putExtra(Const.Key.INTENT_SET_LINK, Data.managerLink);
intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename); intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename);
mm.sendBroadcast(intent); mm.sendBroadcast(intent);

View File

@@ -2,14 +2,15 @@ package com.topjohnwu.magisk.components;
import android.app.Activity; import android.app.Activity;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.StringRes;
import android.support.design.widget.Snackbar;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import androidx.annotation.StringRes;
public class SnackbarMaker { public class SnackbarMaker {
public static Snackbar make(Activity activity, CharSequence text, int duration) { public static Snackbar make(Activity activity, CharSequence text, int duration) {
@@ -34,7 +35,7 @@ public class SnackbarMaker {
} }
private static void setup(Snackbar snack) { private static void setup(Snackbar snack) {
TextView text = snack.getView().findViewById(android.support.design.R.id.snackbar_text); TextView text = snack.getView().findViewById(com.google.android.material.R.id.snackbar_text);
text.setMaxLines(Integer.MAX_VALUE); text.setMaxLines(Integer.MAX_VALUE);
} }

View File

@@ -5,7 +5,6 @@ import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.widget.Toast; import android.widget.Toast;
@@ -19,6 +18,8 @@ import com.topjohnwu.magisk.utils.Download;
import com.topjohnwu.magisk.utils.Utils; import com.topjohnwu.magisk.utils.Utils;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import androidx.annotation.NonNull;
public class UninstallDialog extends CustomAlertDialog { public class UninstallDialog extends CustomAlertDialog {
public UninstallDialog(@NonNull Activity activity) { public UninstallDialog(@NonNull Activity activity) {
@@ -44,7 +45,7 @@ public class UninstallDialog extends CustomAlertDialog {
Download.receive(activity, new DownloadReceiver() { Download.receive(activity, new DownloadReceiver() {
@Override @Override
public void onDownloadDone(Context context, Uri uri) { public void onDownloadDone(Context context, Uri uri) {
Intent intent = new Intent(context, FlashActivity.class) Intent intent = new Intent(context, Data.classMap.get(FlashActivity.class))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setData(uri) .setData(uri)
.putExtra(Const.Key.FLASH_ACTION, Const.Value.UNINSTALL); .putExtra(Const.Key.FLASH_ACTION, Const.Value.UNINSTALL);

View File

@@ -1,29 +1,35 @@
package com.topjohnwu.magisk.container; package com.topjohnwu.magisk.container;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
import android.support.annotation.NonNull;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
public abstract class BaseModule implements Comparable<BaseModule> { public abstract class BaseModule implements Comparable<BaseModule> {
private String mId = null, mName, mVersion, mAuthor, mDescription; private String mId, mName, mVersion, mAuthor, mDescription;
private int mVersionCode = -1, minMagiskVersion = -1; private int mVersionCode = -1, minMagiskVersion = -1;
protected BaseModule() {} protected BaseModule() {
mId = mName = mVersion = mAuthor = mDescription = "";
}
protected BaseModule(Cursor c) { protected BaseModule(Cursor c) {
mId = c.getString(c.getColumnIndex("id")); mId = nonNull(c.getString(c.getColumnIndex("id")));
mName = c.getString(c.getColumnIndex("name")); mName = nonNull(c.getString(c.getColumnIndex("name")));
mVersion = c.getString(c.getColumnIndex("version")); mVersion = nonNull(c.getString(c.getColumnIndex("version")));
mVersionCode = c.getInt(c.getColumnIndex("versionCode")); mVersionCode = c.getInt(c.getColumnIndex("versionCode"));
mAuthor = c.getString(c.getColumnIndex("author")); mAuthor = nonNull(c.getString(c.getColumnIndex("author")));
mDescription = c.getString(c.getColumnIndex("description")); mDescription = nonNull(c.getString(c.getColumnIndex("description")));
minMagiskVersion = c.getInt(c.getColumnIndex("minMagisk")); minMagiskVersion = c.getInt(c.getColumnIndex("minMagisk"));
} }
private String nonNull(String s) {
return s == null ? "" : s;
}
public ContentValues getContentValues() { public ContentValues getContentValues() {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put("id", mId); values.put("id", mId);

View File

@@ -4,7 +4,8 @@ import android.content.ContentValues;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.database.Cursor; import android.database.Cursor;
import android.support.annotation.NonNull;
import androidx.annotation.NonNull;
public class Policy implements Comparable<Policy>{ public class Policy implements Comparable<Policy>{

View File

@@ -2,6 +2,7 @@ package com.topjohnwu.magisk.container;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
import android.text.TextUtils;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.utils.Download; import com.topjohnwu.magisk.utils.Download;
@@ -35,7 +36,7 @@ public class Repo extends BaseModule {
throw new IllegalRepoException("Repo [" + repoName + "] parse error: " + e.getMessage()); throw new IllegalRepoException("Repo [" + repoName + "] parse error: " + e.getMessage());
} }
if (getId() == null) { if (TextUtils.isEmpty(getId())) {
throw new IllegalRepoException("Repo [" + repoName + "] does not contain id"); throw new IllegalRepoException("Repo [" + repoName + "] does not contain id");
} }
if (getVersionCode() < 0) { if (getVersionCode() < 0) {

View File

@@ -1,7 +1,5 @@
package com.topjohnwu.magisk.container; package com.topjohnwu.magisk.container;
import android.support.annotation.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -9,6 +7,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import androidx.annotation.NonNull;
public class ValueSortedMap<K, V extends Comparable<? super V>> extends HashMap<K, V> { public class ValueSortedMap<K, V extends Comparable<? super V>> extends HashMap<K, V> {
private List<V> sorted = new ArrayList<>(); private List<V> sorted = new ArrayList<>();

View File

@@ -7,7 +7,6 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.os.Build; import android.os.Build;
import android.os.Process; import android.os.Process;
import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.widget.Toast; import android.widget.Toast;
@@ -29,9 +28,12 @@ import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import androidx.annotation.NonNull;
public class MagiskDatabaseHelper { public class MagiskDatabaseHelper {
private static final int DATABASE_VER = 6; private static final int DATABASE_VER = 6;
private static final int OLD_DATABASE_VER = 5;
private static final String POLICY_TABLE = "policies"; private static final String POLICY_TABLE = "policies";
private static final String LOG_TABLE = "logs"; private static final String LOG_TABLE = "logs";
private static final String SETTINGS_TABLE = "settings"; private static final String SETTINGS_TABLE = "settings";
@@ -57,13 +59,15 @@ public class MagiskDatabaseHelper {
pm = mm.getPackageManager(); pm = mm.getPackageManager();
db = openDatabase(mm); db = openDatabase(mm);
db.disableWriteAheadLogging(); db.disableWriteAheadLogging();
int version = db.getVersion(); int version = Data.magiskVersionCode >= Const.MAGISK_VER.DBVER_SIX ? DATABASE_VER : OLD_DATABASE_VER;
if (version < DATABASE_VER) { int curVersion = db.getVersion();
onUpgrade(db, version); if (curVersion < version) {
} else if (version > DATABASE_VER) { onUpgrade(db, curVersion);
} else if (curVersion > DATABASE_VER) {
/* Higher than we can possibly support */
onDowngrade(db); onDowngrade(db);
} }
db.setVersion(DATABASE_VER); db.setVersion(version);
clearOutdated(); clearOutdated();
} }

View File

@@ -2,36 +2,32 @@ package com.topjohnwu.magisk.fragments;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.google.android.material.tabs.TabLayout;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MainActivity; import com.topjohnwu.magisk.MainActivity;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.TabFragmentAdapter; import com.topjohnwu.magisk.adapters.TabFragmentAdapter;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
import butterknife.BindView; import androidx.viewpager.widget.ViewPager;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class LogFragment extends BaseFragment { public class LogFragment extends BaseFragment {
private Unbinder unbinder; public ViewPager viewPager;
public TabLayout tab;
@BindView(R.id.container) ViewPager viewPager;
@BindView(R.id.tab) TabLayout tab;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_log, container, false); View v = inflater.inflate(R.layout.fragment_log, container, false);
unbinder = ButterKnife.bind(this, v); ViewBinder.bind(this, v);
((MainActivity) requireActivity()).toolbar.setElevation(0); ((MainActivity) requireActivity()).toolbar.setElevation(0);
@@ -52,7 +48,6 @@ public class LogFragment extends BaseFragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
unbinder.unbind(); ViewBinder.unbind(this);
} }
} }

View File

@@ -5,11 +5,6 @@ import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -25,6 +20,7 @@ import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MainActivity; import com.topjohnwu.magisk.MainActivity;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.asyncs.CheckSafetyNet; import com.topjohnwu.magisk.asyncs.CheckSafetyNet;
import com.topjohnwu.magisk.asyncs.CheckUpdates; import com.topjohnwu.magisk.asyncs.CheckUpdates;
import com.topjohnwu.magisk.components.BaseActivity; import com.topjohnwu.magisk.components.BaseActivity;
@@ -41,55 +37,53 @@ import com.topjohnwu.magisk.utils.Topic;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils; import com.topjohnwu.superuser.ShellUtils;
import butterknife.BindColor; import androidx.annotation.NonNull;
import butterknife.BindView; import androidx.annotation.Nullable;
import butterknife.ButterKnife; import androidx.annotation.StringRes;
import butterknife.OnClick; import androidx.cardview.widget.CardView;
import butterknife.Unbinder; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
public class MagiskFragment extends BaseFragment public class MagiskFragment extends BaseFragment
implements SwipeRefreshLayout.OnRefreshListener, ExpandableView, Topic.Subscriber { implements SwipeRefreshLayout.OnRefreshListener, ExpandableView, Topic.Subscriber {
private Container expandableContainer = new Container(); private Container expandableContainer = new Container();
private Unbinder unbinder;
private static boolean shownDialog = false; private static boolean shownDialog = false;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout; public SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.core_only_notice) CardView coreOnlyNotice; public CardView coreOnlyNotice;
@BindView(R.id.magisk_update) RelativeLayout magiskUpdate; public RelativeLayout magiskUpdate;
@BindView(R.id.magisk_update_icon) ImageView magiskUpdateIcon; public ImageView magiskUpdateIcon;
@BindView(R.id.magisk_update_status) TextView magiskUpdateText; public TextView magiskUpdateText;
@BindView(R.id.magisk_update_progress) ProgressBar magiskUpdateProgress; public ProgressBar magiskUpdateProgress;
@BindView(R.id.magisk_status_icon) ImageView magiskStatusIcon; public ImageView magiskStatusIcon;
@BindView(R.id.magisk_version) TextView magiskVersionText; public TextView magiskVersionText;
@BindView(R.id.safetyNet_card) CardView safetyNetCard; public CardView safetyNetCard;
@BindView(R.id.safetyNet_refresh) ImageView safetyNetRefreshIcon; public ImageView safetyNetRefreshIcon;
@BindView(R.id.safetyNet_status) TextView safetyNetStatusText; public TextView safetyNetStatusText;
@BindView(R.id.safetyNet_check_progress) ProgressBar safetyNetProgress; public ProgressBar safetyNetProgress;
@BindView(R.id.expand_layout) LinearLayout expandLayout; public LinearLayout expandLayout;
@BindView(R.id.cts_status_icon) ImageView ctsStatusIcon; public ImageView ctsStatusIcon;
@BindView(R.id.cts_status) TextView ctsStatusText; public TextView ctsStatusText;
@BindView(R.id.basic_status_icon) ImageView basicStatusIcon; public ImageView basicStatusIcon;
@BindView(R.id.basic_status) TextView basicStatusText; public TextView basicStatusText;
@BindView(R.id.install_option_card) CardView installOptionCard; public CardView installOptionCard;
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox; public CheckBox keepEncChkbox;
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox; public CheckBox keepVerityChkbox;
@BindView(R.id.install_button) CardView installButton; public CardView installButton;
@BindView(R.id.install_text) TextView installText; public TextView installText;
@BindView(R.id.uninstall_button) CardView uninstallButton; public CardView uninstallButton;
@BindColor(R.color.red500) int colorBad; public int colorBad;
@BindColor(R.color.green500) int colorOK; public int colorOK;
@BindColor(R.color.yellow500) int colorWarn; public int colorWarn;
@BindColor(R.color.grey500) int colorNeutral; public int colorNeutral;
@BindColor(R.color.blue500) int colorInfo; public int colorInfo;
@OnClick(R.id.safetyNet_title) public void safetyNet() {
void safetyNet() {
Runnable task = () -> { Runnable task = () -> {
safetyNetProgress.setVisibility(View.VISIBLE); safetyNetProgress.setVisibility(View.VISIBLE);
safetyNetRefreshIcon.setVisibility(View.GONE); safetyNetRefreshIcon.setVisibility(View.GONE);
@@ -112,8 +106,7 @@ public class MagiskFragment extends BaseFragment
} }
@OnClick(R.id.install_button) public void install() {
void install() {
shownDialog = true; shownDialog = true;
// Show Manager update first // Show Manager update first
@@ -126,8 +119,7 @@ public class MagiskFragment extends BaseFragment
new MagiskInstallDialog((BaseActivity) getActivity()).show(); new MagiskInstallDialog((BaseActivity) getActivity()).show();
} }
@OnClick(R.id.uninstall_button) public void uninstall() {
void uninstall() {
new UninstallDialog(requireActivity()).show(); new UninstallDialog(requireActivity()).show();
} }
@@ -136,7 +128,7 @@ public class MagiskFragment extends BaseFragment
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) { @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_magisk, container, false); View v = inflater.inflate(R.layout.fragment_magisk, container, false);
unbinder = ButterKnife.bind(this, v); ViewBinder.bind(this, v);
requireActivity().setTitle(R.string.magisk); requireActivity().setTitle(R.string.magisk);
expandableContainer.expandLayout = expandLayout; expandableContainer.expandLayout = expandLayout;
@@ -153,6 +145,12 @@ public class MagiskFragment extends BaseFragment
return v; return v;
} }
@Override
public void onDestroyView() {
super.onDestroyView();
ViewBinder.unbind(this);
}
@Override @Override
public void onRefresh() { public void onRefresh() {
Data.loadMagiskInfo(); Data.loadMagiskInfo();
@@ -196,12 +194,6 @@ public class MagiskFragment extends BaseFragment
} }
} }
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override @Override
public Container getContainer() { public Container getContainer() {
return expandableContainer; return expandableContainer;

View File

@@ -1,10 +1,6 @@
package com.topjohnwu.magisk.fragments; package com.topjohnwu.magisk.fragments;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@@ -13,19 +9,20 @@ import android.view.ViewGroup;
import android.widget.SearchView; import android.widget.SearchView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.ApplicationAdapter; import com.topjohnwu.magisk.adapters.ApplicationAdapter;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.utils.Topic; import com.topjohnwu.magisk.utils.Topic;
import butterknife.BindView; import androidx.annotation.NonNull;
import butterknife.ButterKnife; import androidx.annotation.Nullable;
import butterknife.Unbinder; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber { public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber {
private Unbinder unbinder; public SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout; public RecyclerView recyclerView;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
SearchView search; SearchView search;
private ApplicationAdapter appAdapter; private ApplicationAdapter appAdapter;
@@ -42,7 +39,7 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull 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); ViewBinder.bind(this, view);
appAdapter = new ApplicationAdapter(requireActivity()); appAdapter = new ApplicationAdapter(requireActivity());
recyclerView.setAdapter(appAdapter); recyclerView.setAdapter(appAdapter);
@@ -79,7 +76,7 @@ public class MagiskHideFragment extends BaseFragment implements Topic.Subscriber
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
unbinder.unbind(); ViewBinder.unbind(this);
} }
@Override @Override

View File

@@ -2,8 +2,6 @@ package com.topjohnwu.magisk.fragments;
import android.Manifest; import android.Manifest;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@@ -16,8 +14,10 @@ import android.widget.ProgressBar;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.snackbar.Snackbar;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.components.SnackbarMaker; import com.topjohnwu.magisk.components.SnackbarMaker;
import com.topjohnwu.magisk.utils.Download; import com.topjohnwu.magisk.utils.Download;
@@ -28,24 +28,20 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Calendar; import java.util.Calendar;
import butterknife.BindView; import androidx.annotation.Nullable;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public class MagiskLogFragment extends BaseFragment { public class MagiskLogFragment extends BaseFragment {
private Unbinder unbinder; public TextView txtLog;
public ScrollView svLog;
@BindView(R.id.txtLog) TextView txtLog; public HorizontalScrollView hsvLog;
@BindView(R.id.svLog) ScrollView svLog; public ProgressBar progressBar;
@BindView(R.id.hsvLog) HorizontalScrollView hsvLog;
@BindView(R.id.progressBar) ProgressBar progressBar;
@Nullable @Nullable
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_magisk_log, container, false); View view = inflater.inflate(R.layout.fragment_magisk_log, container, false);
unbinder = ButterKnife.bind(this, view); ViewBinder.bind(this, view);
setHasOptionsMenu(true); setHasOptionsMenu(true);
txtLog.setTextIsSelectable(true); txtLog.setTextIsSelectable(true);
return view; return view;
@@ -66,7 +62,7 @@ public class MagiskLogFragment extends BaseFragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
unbinder.unbind(); ViewBinder.unbind(this);
} }
@Override @Override

View File

@@ -4,10 +4,6 @@ import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@@ -17,8 +13,10 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.FlashActivity; import com.topjohnwu.magisk.FlashActivity;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.ModulesAdapter; import com.topjohnwu.magisk.adapters.ModulesAdapter;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.container.Module; import com.topjohnwu.magisk.container.Module;
@@ -30,18 +28,17 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import butterknife.BindView; import androidx.annotation.NonNull;
import butterknife.ButterKnife; import androidx.annotation.Nullable;
import butterknife.OnClick; import androidx.recyclerview.widget.RecyclerView;
import butterknife.Unbinder; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
public class ModulesFragment extends BaseFragment implements Topic.Subscriber { public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
private Unbinder unbinder; public SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout; public RecyclerView recyclerView;
@BindView(R.id.recyclerView) RecyclerView recyclerView; public TextView emptyRv;
@BindView(R.id.empty_rv) TextView emptyRv;
@OnClick(R.id.fab)
public void selectFile() { public void selectFile() {
runWithPermission(new String[] { 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);
@@ -56,7 +53,7 @@ public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_modules, container, false); View view = inflater.inflate(R.layout.fragment_modules, container, false);
unbinder = ButterKnife.bind(this, view); ViewBinder.bind(this, view);
setHasOptionsMenu(true); setHasOptionsMenu(true);
mSwipeRefreshLayout.setOnRefreshListener(() -> { mSwipeRefreshLayout.setOnRefreshListener(() -> {
@@ -95,7 +92,7 @@ public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Const.ID.FETCH_ZIP && resultCode == Activity.RESULT_OK && data != null) { if (requestCode == Const.ID.FETCH_ZIP && resultCode == Activity.RESULT_OK && data != null) {
// Get the URI of the selected file // Get the URI of the selected file
Intent intent = new Intent(getActivity(), FlashActivity.class); Intent intent = new Intent(getActivity(), Data.classMap.get(FlashActivity.class));
intent.setData(data.getData()).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP); intent.setData(data.getData()).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP);
startActivity(intent); startActivity(intent);
} }
@@ -104,7 +101,7 @@ public class ModulesFragment extends BaseFragment implements Topic.Subscriber {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
unbinder.unbind(); ViewBinder.unbind(this);
} }
@Override @Override

View File

@@ -2,10 +2,6 @@ package com.topjohnwu.magisk.fragments;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@@ -18,6 +14,7 @@ import android.widget.TextView;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.ReposAdapter; import com.topjohnwu.magisk.adapters.ReposAdapter;
import com.topjohnwu.magisk.asyncs.UpdateRepos; import com.topjohnwu.magisk.asyncs.UpdateRepos;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
@@ -26,16 +23,16 @@ import com.topjohnwu.magisk.utils.Topic;
import java.util.Map; import java.util.Map;
import butterknife.BindView; import androidx.annotation.NonNull;
import butterknife.ButterKnife; import androidx.annotation.Nullable;
import butterknife.Unbinder; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
public class ReposFragment extends BaseFragment implements Topic.Subscriber { public class ReposFragment extends BaseFragment implements Topic.Subscriber {
private Unbinder unbinder; public RecyclerView recyclerView;
@BindView(R.id.recyclerView) RecyclerView recyclerView; public TextView emptyRv;
@BindView(R.id.empty_rv) TextView emptyRv; public SwipeRefreshLayout mSwipeRefreshLayout;
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
private ReposAdapter adapter; private ReposAdapter adapter;
@@ -49,7 +46,7 @@ public class ReposFragment extends BaseFragment implements Topic.Subscriber {
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_repos, container, false); View view = inflater.inflate(R.layout.fragment_repos, container, false);
unbinder = ButterKnife.bind(this, view); ViewBinder.bind(this, view);
mSwipeRefreshLayout.setRefreshing(true); mSwipeRefreshLayout.setRefreshing(true);
recyclerView.setVisibility(View.GONE); recyclerView.setVisibility(View.GONE);
@@ -123,6 +120,6 @@ public class ReposFragment extends BaseFragment implements Topic.Subscriber {
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
mm.repoDB.unregisterAdapter(); mm.repoDB.unregisterAdapter();
unbinder.unbind(); ViewBinder.unbind(this);
} }
} }

View File

@@ -1,5 +1,6 @@
package com.topjohnwu.magisk.fragments; package com.topjohnwu.magisk.fragments;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
@@ -10,13 +11,6 @@ import android.hardware.fingerprint.FingerprintManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v14.preference.SwitchPreference;
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.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -44,6 +38,17 @@ import com.topjohnwu.superuser.ShellUtils;
import java.io.IOException; import java.io.IOException;
import java.util.Locale; import java.util.Locale;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroupAdapter;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
import androidx.recyclerview.widget.RecyclerView;
public class SettingsFragment extends PreferenceFragmentCompat public class SettingsFragment extends PreferenceFragmentCompat
implements SharedPreferences.OnSharedPreferenceChangeListener, implements SharedPreferences.OnSharedPreferenceChangeListener,
Topic.Subscriber, Topic.AutoSubscriber { Topic.Subscriber, Topic.AutoSubscriber {
@@ -221,7 +226,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
setSummary(); setSummary();
switch (key) { switch (key) {
case Const.Key.DARK_THEME: case Const.Key.DARK_THEME:
Topic.publish(false, Topic.RELOAD_ACTIVITY); requireActivity().recreate();
break; break;
case Const.Key.COREONLY: case Const.Key.COREONLY:
if (prefs.getBoolean(key, false)) { if (prefs.getBoolean(key, false)) {
@@ -253,7 +258,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
break; break;
case Const.Key.LOCALE: case Const.Key.LOCALE:
LocaleManager.setLocale(mm); LocaleManager.setLocale(mm);
Topic.publish(false, Topic.RELOAD_ACTIVITY); requireActivity().recreate();
break; break;
case Const.Key.UPDATE_CHANNEL: case Const.Key.UPDATE_CHANNEL:
case Const.Key.CUSTOM_CHANNEL: case Const.Key.CUSTOM_CHANNEL:
@@ -352,4 +357,38 @@ public class SettingsFragment extends PreferenceFragmentCompat
public int[] getSubscribedTopics() { public int[] getSubscribedTopics() {
return new int[] {Topic.LOCALE_FETCH_DONE}; return new int[] {Topic.LOCALE_FETCH_DONE};
} }
@Override
protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
return new PreferenceGroupAdapter(preferenceScreen) {
@SuppressLint("RestrictedApi")
@Override
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
Preference preference = getItem(position);
if (preference instanceof PreferenceCategory)
setZeroPaddingToLayoutChildren(holder.itemView);
else {
View iconFrame = holder.itemView.findViewById(R.id.icon_frame);
if (iconFrame != null) {
iconFrame.setVisibility(preference.getIcon() == null ? View.GONE : View.VISIBLE);
}
}
}
};
}
private void setZeroPaddingToLayoutChildren(View view) {
if (!(view instanceof ViewGroup))
return;
ViewGroup viewGroup = (ViewGroup) view;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
setZeroPaddingToLayoutChildren(viewGroup.getChildAt(i));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
viewGroup.setPaddingRelative(0, viewGroup.getPaddingTop(), viewGroup.getPaddingEnd(), viewGroup.getPaddingBottom());
else
viewGroup.setPadding(0, viewGroup.getPaddingTop(), viewGroup.getPaddingRight(), viewGroup.getPaddingBottom());
}
}
} }

View File

@@ -1,8 +1,6 @@
package com.topjohnwu.magisk.fragments; package com.topjohnwu.magisk.fragments;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@@ -12,19 +10,18 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.SuLogAdapter; import com.topjohnwu.magisk.adapters.SuLogAdapter;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
import butterknife.BindView; import androidx.annotation.Nullable;
import butterknife.ButterKnife; import androidx.recyclerview.widget.RecyclerView;
import butterknife.Unbinder;
public class SuLogFragment extends BaseFragment { public class SuLogFragment extends BaseFragment {
@BindView(R.id.empty_rv) TextView emptyRv; public TextView emptyRv;
@BindView(R.id.recyclerView) RecyclerView recyclerView; public RecyclerView recyclerView;
private Unbinder unbinder;
private SuLogAdapter adapter; private SuLogAdapter adapter;
@Override @Override
@@ -44,7 +41,7 @@ public class SuLogFragment extends BaseFragment {
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_su_log, container, false); View v = inflater.inflate(R.layout.fragment_su_log, container, false);
unbinder = ButterKnife.bind(this, v); ViewBinder.bind(this, v);
adapter = new SuLogAdapter(mm.mDB); adapter = new SuLogAdapter(mm.mDB);
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
@@ -83,6 +80,6 @@ public class SuLogFragment extends BaseFragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
unbinder.unbind(); ViewBinder.unbind(this);
} }
} }

View File

@@ -2,36 +2,34 @@ package com.topjohnwu.magisk.fragments;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.ViewBinder;
import com.topjohnwu.magisk.adapters.PolicyAdapter; import com.topjohnwu.magisk.adapters.PolicyAdapter;
import com.topjohnwu.magisk.components.BaseFragment; import com.topjohnwu.magisk.components.BaseFragment;
import com.topjohnwu.magisk.container.Policy; import com.topjohnwu.magisk.container.Policy;
import java.util.List; import java.util.List;
import butterknife.BindView; import androidx.annotation.Nullable;
import butterknife.ButterKnife; import androidx.recyclerview.widget.RecyclerView;
import butterknife.Unbinder;
public class SuperuserFragment extends BaseFragment { public class SuperuserFragment extends BaseFragment {
private Unbinder unbinder; public RecyclerView recyclerView;
public TextView emptyRv;
private PackageManager pm; private PackageManager pm;
@BindView(R.id.recyclerView) RecyclerView recyclerView;
@BindView(R.id.empty_rv) TextView emptyRv;
@Nullable @Nullable
@Override @Override
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_superuser, container, false); View view = inflater.inflate(R.layout.fragment_superuser, container, false);
unbinder = ButterKnife.bind(this, view); ViewBinder.bind(this, view);
pm = getActivity().getPackageManager(); pm = getActivity().getPackageManager();
return view; return view;
@@ -52,7 +50,7 @@ public class SuperuserFragment extends BaseFragment {
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
unbinder.unbind(); ViewBinder.unbind(this);
} }
private void displayPolicyList() { private void displayPolicyList() {

View File

@@ -5,14 +5,31 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils; import android.text.TextUtils;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.SuRequestActivity;
import com.topjohnwu.magisk.services.OnBootService; import com.topjohnwu.magisk.services.OnBootService;
import com.topjohnwu.magisk.utils.SuConnector;
public class BootReceiver extends BroadcastReceiver { public class BootReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)) if (TextUtils.equals(intent.getAction(), Intent.ACTION_BOOT_COMPLETED)) {
OnBootService.enqueueWork(context); switch (intent.getExtras().getString("action", "boot")) {
case "request":
Intent i = new Intent(context, Data.classMap.get(SuRequestActivity.class))
.putExtra("socket", intent.getStringExtra("socket"))
.putExtra("version", 2)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
break;
case "log":
SuConnector.handleLogs(intent, 2);
break;
case "boot":
OnBootService.enqueueWork(context);
break;
}
}
} }
} }

View File

@@ -7,7 +7,6 @@ import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager; import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.os.Build; import android.os.Build;
import android.support.annotation.RequiresApi;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
@@ -18,6 +17,8 @@ import com.topjohnwu.superuser.Shell;
import java.util.ArrayList; import java.util.ArrayList;
import androidx.annotation.RequiresApi;
public class ShortcutReceiver extends BroadcastReceiver { public class ShortcutReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@@ -36,7 +37,7 @@ public class ShortcutReceiver extends BroadcastReceiver {
Data.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) { Data.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
shortCuts.add(new ShortcutInfo.Builder(mm, "superuser") shortCuts.add(new ShortcutInfo.Builder(mm, "superuser")
.setShortLabel(mm.getString(R.string.superuser)) .setShortLabel(mm.getString(R.string.superuser))
.setIntent(new Intent(mm, SplashActivity.class) .setIntent(new Intent(mm, Data.classMap.get(SplashActivity.class))
.putExtra(Const.Key.OPEN_SECTION, "superuser") .putExtra(Const.Key.OPEN_SECTION, "superuser")
.setAction(Intent.ACTION_VIEW) .setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
@@ -48,7 +49,7 @@ public class ShortcutReceiver extends BroadcastReceiver {
&& mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false)) { && mm.prefs.getBoolean(Const.Key.MAGISKHIDE, false)) {
shortCuts.add(new ShortcutInfo.Builder(mm, "magiskhide") shortCuts.add(new ShortcutInfo.Builder(mm, "magiskhide")
.setShortLabel(mm.getString(R.string.magiskhide)) .setShortLabel(mm.getString(R.string.magiskhide))
.setIntent(new Intent(mm, SplashActivity.class) .setIntent(new Intent(mm, Data.classMap.get(SplashActivity.class))
.putExtra(Const.Key.OPEN_SECTION, "magiskhide") .putExtra(Const.Key.OPEN_SECTION, "magiskhide")
.setAction(Intent.ACTION_VIEW) .setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
@@ -59,7 +60,7 @@ public class ShortcutReceiver extends BroadcastReceiver {
if (!mm.prefs.getBoolean(Const.Key.COREONLY, false) && root && Data.magiskVersionCode >= 0) { if (!mm.prefs.getBoolean(Const.Key.COREONLY, false) && root && Data.magiskVersionCode >= 0) {
shortCuts.add(new ShortcutInfo.Builder(mm, "modules") shortCuts.add(new ShortcutInfo.Builder(mm, "modules")
.setShortLabel(mm.getString(R.string.modules)) .setShortLabel(mm.getString(R.string.modules))
.setIntent(new Intent(mm, SplashActivity.class) .setIntent(new Intent(mm, Data.classMap.get(SplashActivity.class))
.putExtra(Const.Key.OPEN_SECTION, "modules") .putExtra(Const.Key.OPEN_SECTION, "modules")
.setAction(Intent.ACTION_VIEW) .setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))
@@ -68,7 +69,7 @@ public class ShortcutReceiver extends BroadcastReceiver {
.build()); .build());
shortCuts.add(new ShortcutInfo.Builder(mm, "downloads") shortCuts.add(new ShortcutInfo.Builder(mm, "downloads")
.setShortLabel(mm.getString(R.string.download)) .setShortLabel(mm.getString(R.string.download))
.setIntent(new Intent(mm, SplashActivity.class) .setIntent(new Intent(mm, Data.classMap.get(SplashActivity.class))
.putExtra(Const.Key.OPEN_SECTION, "downloads") .putExtra(Const.Key.OPEN_SECTION, "downloads")
.setAction(Intent.ACTION_VIEW) .setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK))

View File

@@ -2,18 +2,20 @@ package com.topjohnwu.magisk.services;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.JobIntentService;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.utils.NotificationMgr; import com.topjohnwu.magisk.utils.NotificationMgr;
import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ShellUtils; import com.topjohnwu.superuser.ShellUtils;
import androidx.annotation.NonNull;
import androidx.core.app.JobIntentService;
public class OnBootService extends JobIntentService { public class OnBootService extends JobIntentService {
public static void enqueueWork(Context context) { public static void enqueueWork(Context context) {
enqueueWork(context, OnBootService.class, Const.ID.ONBOOT_SERVICE_ID, new Intent()); enqueueWork(context, Data.classMap.get(OnBootService.class), Const.ID.ONBOOT_SERVICE_ID, new Intent());
} }
@Override @Override

View File

@@ -1,297 +1,21 @@
package com.topjohnwu.magisk.superuser; package com.topjohnwu.magisk.superuser;
import android.content.ContentValues;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.FileObserver;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.SuRequestActivity;
import com.topjohnwu.magisk.asyncs.ParallelTask;
import com.topjohnwu.magisk.components.BaseActivity; import com.topjohnwu.magisk.components.BaseActivity;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.utils.FingerprintHelper;
import java.io.DataInputStream;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
public class RequestActivity extends BaseActivity { public class RequestActivity extends BaseActivity {
@BindView(R.id.su_popup) LinearLayout suPopup;
@BindView(R.id.timeout) Spinner timeout;
@BindView(R.id.app_icon) ImageView appIcon;
@BindView(R.id.app_name) TextView appNameView;
@BindView(R.id.package_name) TextView packageNameView;
@BindView(R.id.grant_btn) Button grant_btn;
@BindView(R.id.deny_btn) Button deny_btn;
@BindView(R.id.fingerprint) ImageView fingerprintImg;
@BindView(R.id.warning) TextView warning;
private String socketPath;
private LocalSocket socket;
private PackageManager pm;
private boolean hasTimeout;
private Policy policy;
private CountDownTimer timer;
private FingerprintHelper fingerprintHelper;
@Override
public int getDarkTheme() {
return R.style.SuRequest_Dark;
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE); Intent intent = new Intent(this, Data.classMap.get(SuRequestActivity.class))
.putExtra("socket", getIntent().getStringExtra("socket"))
pm = getPackageManager(); .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mm.mDB.clearOutdated(); startActivity(intent);
Intent intent = getIntent();
socketPath = intent.getStringExtra("socket");
hasTimeout = intent.getBooleanExtra("timeout", true);
new FileObserver(socketPath) {
@Override
public void onEvent(int fileEvent, String path) {
if (fileEvent == FileObserver.DELETE_SELF) {
finish();
}
}
}.startWatching();
new SocketManager(this).exec();
}
@Override
public void finish() {
if (timer != null)
timer.cancel();
if (fingerprintHelper != null)
fingerprintHelper.cancel();
super.finish();
}
private boolean cancelTimeout() {
timer.cancel();
deny_btn.setText(getString(R.string.deny));
return false;
}
private void showRequest() {
switch (Data.suResponseType) {
case Const.Value.SU_AUTO_DENY:
handleAction(Policy.DENY, 0);
return;
case Const.Value.SU_AUTO_ALLOW:
handleAction(Policy.ALLOW, 0);
return;
case Const.Value.SU_PROMPT:
default:
}
// If not interactive, response directly
if (policy.policy != Policy.INTERACTIVE) {
handleAction();
return;
}
setContentView(R.layout.activity_request);
ButterKnife.bind(this);
appIcon.setImageDrawable(policy.info.loadIcon(pm));
appNameView.setText(policy.appName);
packageNameView.setText(policy.packageName);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.allow_timeout, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
timeout.setAdapter(adapter);
timer = new CountDownTimer(Data.suRequestTimeout * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
deny_btn.setText(getString(R.string.deny_with_str, "(" + millisUntilFinished / 1000 + ")"));
}
@Override
public void onFinish() {
deny_btn.setText(getString(R.string.deny_with_str, "(0)"));
handleAction(Policy.DENY);
}
};
boolean useFingerprint = Data.suFingerprint && FingerprintHelper.canUseFingerprint();
if (useFingerprint) {
try {
fingerprintHelper = new FingerprintHelper() {
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
warning.setText(errString);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
warning.setText(helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
handleAction(Policy.ALLOW);
}
@Override
public void onAuthenticationFailed() {
warning.setText(R.string.auth_fail);
}
};
fingerprintHelper.authenticate();
} catch (Exception e) {
e.printStackTrace();
useFingerprint = false;
}
}
if (!useFingerprint) {
grant_btn.setOnClickListener(v -> {
handleAction(Policy.ALLOW);
timer.cancel();
});
grant_btn.requestFocus();
}
grant_btn.setVisibility(useFingerprint ? View.GONE : View.VISIBLE);
fingerprintImg.setVisibility(useFingerprint ? View.VISIBLE : View.GONE);
deny_btn.setOnClickListener(v -> {
handleAction(Policy.DENY);
timer.cancel();
});
suPopup.setOnClickListener(v -> cancelTimeout());
timeout.setOnTouchListener((v, event) -> cancelTimeout());
if (hasTimeout) {
timer.start();
} else {
cancelTimeout();
}
}
@Override
public void onBackPressed() {
if (policy != null) {
handleAction(Policy.DENY);
} else {
finish();
}
}
void handleAction() {
String response;
if (policy.policy == Policy.ALLOW) {
response = "socket:ALLOW";
} else {
response = "socket:DENY";
}
try {
socket.getOutputStream().write((response).getBytes());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
finish(); finish();
} }
void handleAction(int action) {
handleAction(action, Const.Value.timeoutList[timeout.getSelectedItemPosition()]);
}
void handleAction(int action, int time) {
policy.policy = action;
if (time >= 0) {
policy.until = (time == 0) ? 0 : (System.currentTimeMillis() / 1000 + time * 60);
mm.mDB.addPolicy(policy);
}
handleAction();
}
private class SocketManager extends ParallelTask<Void, Void, Boolean> {
SocketManager(BaseActivity context) {
super(context);
}
@Override
protected Boolean doInBackground(Void... params) {
try {
socket = new LocalSocket();
socket.connect(new LocalSocketAddress(socketPath, LocalSocketAddress.Namespace.FILESYSTEM));
DataInputStream is = new DataInputStream(socket.getInputStream());
ContentValues payload = new ContentValues();
while (true) {
int nameLen = is.readInt();
byte[] nameBytes = new byte[nameLen];
is.readFully(nameBytes);
String name = new String(nameBytes);
if (TextUtils.equals(name, "eof"))
break;
int dataLen = is.readInt();
byte[] dataBytes = new byte[dataLen];
is.readFully(dataBytes);
String data = new String(dataBytes);
payload.put(name, data);
}
if (payload.getAsInteger("uid") == null) {
return false;
}
int uid = payload.getAsInteger("uid");
policy = mm.mDB.getPolicy(uid);
if (policy == null) {
policy = new Policy(uid, pm);
}
/* Never allow com.topjohnwu.magisk (could be malware) */
if (TextUtils.equals(policy.packageName, Const.ORIG_PKG_NAME))
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
showRequest();
} else {
finish();
}
}
}
} }

View File

@@ -3,88 +3,13 @@ package com.topjohnwu.magisk.superuser;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Process;
import android.widget.Toast;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.utils.SuConnector;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.container.SuLogEntry;
import com.topjohnwu.magisk.utils.Utils;
import java.util.Date;
public class SuReceiver extends BroadcastReceiver { public class SuReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
int fromUid, toUid, pid, mode; SuConnector.handleLogs(intent, 1);
String command, action;
Policy policy;
MagiskManager mm = Data.MM();
if (intent == null) return;
mode = intent.getIntExtra("mode", -1);
if (mode < 0) return;
if (mode == Const.Value.NOTIFY_USER_TO_OWNER) {
Utils.toast(R.string.multiuser_hint_owner_request, Toast.LENGTH_LONG);
return;
}
fromUid = intent.getIntExtra("from.uid", -1);
if (fromUid < 0) return;
if (fromUid == Process.myUid()) return; // Don't show anything if it's Magisk Manager
action = intent.getStringExtra("action");
if (action == null) return;
policy = mm.mDB.getPolicy(fromUid);
if (policy == null) {
try {
policy = new Policy(fromUid, mm.getPackageManager());
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return;
}
}
SuLogEntry log = new SuLogEntry(policy);
String message;
switch (action) {
case "allow":
message = mm.getString(R.string.su_allow_toast, policy.appName);
log.action = true;
break;
case "deny":
message = mm.getString(R.string.su_deny_toast, policy.appName);
log.action = false;
break;
default:
return;
}
if (policy.notification && Data.suNotificationType == Const.Value.NOTIFICATION_TOAST)
Utils.toast(message, Toast.LENGTH_SHORT);
if (mode == Const.Value.NOTIFY_NORMAL_LOG && policy.logging) {
toUid = intent.getIntExtra("to.uid", -1);
if (toUid < 0) return;
pid = intent.getIntExtra("pid", -1);
if (pid < 0) return;
command = intent.getStringExtra("command");
if (command == null) return;
log.toUid = toUid;
log.fromPid = pid;
log.command = command;
log.date = new Date();
mm.mDB.addLog(log);
}
} }
} }

View File

@@ -1,12 +1,12 @@
package com.topjohnwu.magisk.utils; package com.topjohnwu.magisk.utils;
import android.support.annotation.Keep;
import com.topjohnwu.utils.SignBoot; import com.topjohnwu.utils.SignBoot;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import androidx.annotation.Keep;
public class BootSigner { public class BootSigner {
@Keep @Keep

View File

@@ -1,7 +1,5 @@
package com.topjohnwu.magisk.utils; package com.topjohnwu.magisk.utils;
import android.support.annotation.Keep;
public interface ISafetyNetHelper { public interface ISafetyNetHelper {
int RESPONSE_ERR = 0x01; int RESPONSE_ERR = 0x01;
@@ -10,14 +8,11 @@ public interface ISafetyNetHelper {
int BASIC_PASS = 0x10; int BASIC_PASS = 0x10;
int CTS_PASS = 0x20; int CTS_PASS = 0x20;
@Keep
void attest(); void attest();
@Keep
int getVersion(); int getVersion();
interface Callback { interface Callback {
@Keep
void onResponse(int responseCode); void onResponse(int responseCode);
} }
} }

View File

@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.utils;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.annotation.StringRes;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
@@ -16,6 +15,8 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import androidx.annotation.StringRes;
public class LocaleManager { public class LocaleManager {
public static Locale locale = Locale.getDefault(); public static Locale locale = Locale.getDefault();
public final static Locale defaultLocale = Locale.getDefault(); public final static Locale defaultLocale = Locale.getDefault();

View File

@@ -4,8 +4,6 @@ import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
@@ -15,15 +13,18 @@ import com.topjohnwu.magisk.SplashActivity;
import com.topjohnwu.magisk.receivers.ManagerUpdate; import com.topjohnwu.magisk.receivers.ManagerUpdate;
import com.topjohnwu.magisk.receivers.RebootReceiver; import com.topjohnwu.magisk.receivers.RebootReceiver;
import androidx.core.app.NotificationCompat;
import androidx.core.app.TaskStackBuilder;
public class NotificationMgr { public class NotificationMgr {
public static void magiskUpdate() { public static void magiskUpdate() {
MagiskManager mm = Data.MM(); MagiskManager mm = Data.MM();
Intent intent = new Intent(mm, SplashActivity.class); Intent intent = new Intent(mm, Data.classMap.get(SplashActivity.class));
intent.putExtra(Const.Key.OPEN_SECTION, "magisk"); intent.putExtra(Const.Key.OPEN_SECTION, "magisk");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mm); TaskStackBuilder stackBuilder = TaskStackBuilder.create(mm);
stackBuilder.addParentStack(SplashActivity.class); stackBuilder.addParentStack(Data.classMap.get(SplashActivity.class));
stackBuilder.addNextIntent(intent); stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID, PendingIntent pendingIntent = stackBuilder.getPendingIntent(Const.ID.MAGISK_UPDATE_NOTIFICATION_ID,
PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent.FLAG_UPDATE_CURRENT);
@@ -46,7 +47,7 @@ public class NotificationMgr {
String filename = Utils.fmt("MagiskManager-v%s(%d).apk", String filename = Utils.fmt("MagiskManager-v%s(%d).apk",
Data.remoteManagerVersionString, Data.remoteManagerVersionCode); Data.remoteManagerVersionString, Data.remoteManagerVersionCode);
Intent intent = new Intent(mm, ManagerUpdate.class); Intent intent = new Intent(mm, Data.classMap.get(ManagerUpdate.class));
intent.putExtra(Const.Key.INTENT_SET_LINK, Data.managerLink); intent.putExtra(Const.Key.INTENT_SET_LINK, Data.managerLink);
intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename); intent.putExtra(Const.Key.INTENT_SET_FILENAME, filename);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm, PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
@@ -68,7 +69,7 @@ public class NotificationMgr {
public static void dtboPatched() { public static void dtboPatched() {
MagiskManager mm = Data.MM(); MagiskManager mm = Data.MM();
Intent intent = new Intent(mm, RebootReceiver.class); Intent intent = new Intent(mm, Data.classMap.get(RebootReceiver.class));
PendingIntent pendingIntent = PendingIntent.getBroadcast(mm, PendingIntent pendingIntent = PendingIntent.getBroadcast(mm,
Const.ID.DTBO_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); Const.ID.DTBO_NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);

View File

@@ -1,7 +1,6 @@
package com.topjohnwu.magisk.utils; package com.topjohnwu.magisk.utils;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull;
import com.topjohnwu.magisk.Const; import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
@@ -14,6 +13,8 @@ import com.topjohnwu.superuser.io.SuFile;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import androidx.annotation.NonNull;
public class RootUtils extends Shell.Initializer { public class RootUtils extends Shell.Initializer {
static { static {
@@ -49,7 +50,7 @@ public class RootUtils extends Shell.Initializer {
job.add(nonroot); job.add(nonroot);
} }
job.add("mount_partitions", "get_flags", "run_migrations").exec(); job.add("mount_partitions", "get_flags", "run_migrations", "export BOOTMODE=true").exec();
Data.keepVerity = Boolean.parseBoolean(ShellUtils.fastCmd("echo $KEEPVERITY")); Data.keepVerity = Boolean.parseBoolean(ShellUtils.fastCmd("echo $KEEPVERITY"));
Data.keepEnc = Boolean.parseBoolean(ShellUtils.fastCmd("echo $KEEPFORCEENCRYPT")); Data.keepEnc = Boolean.parseBoolean(ShellUtils.fastCmd("echo $KEEPFORCEENCRYPT"));

View File

@@ -0,0 +1,118 @@
package com.topjohnwu.magisk.utils;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.LocalSocket;
import android.os.Bundle;
import android.os.Process;
import android.text.TextUtils;
import android.widget.Toast;
import com.topjohnwu.magisk.Const;
import com.topjohnwu.magisk.Data;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Policy;
import com.topjohnwu.magisk.container.SuLogEntry;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Date;
public abstract class SuConnector {
protected LocalSocket socket = new LocalSocket();
private String readString(DataInputStream is) throws IOException {
int len = is.readInt();
byte[] buf = new byte[len];
is.readFully(buf);
return new String(buf);
}
public Bundle readSocketInput() throws IOException {
Bundle bundle = new Bundle();
DataInputStream is = new DataInputStream(socket.getInputStream());
while (true) {
String name = readString(is);
if (TextUtils.equals(name, "eof"))
break;
bundle.putString(name, readString(is));
}
return bundle;
}
protected DataOutputStream getOutputStream() throws IOException {
return new DataOutputStream(socket.getOutputStream());
}
public abstract void response();
public static void handleLogs(Intent intent, int version) {
MagiskManager mm = Data.MM();
if (intent == null) return;
int fromUid = intent.getIntExtra("from.uid", -1);
if (fromUid < 0) return;
if (fromUid == Process.myUid()) return;
Policy policy = mm.mDB.getPolicy(fromUid);
if (policy == null) {
try {
policy = new Policy(fromUid, mm.getPackageManager());
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return;
}
}
SuLogEntry log = new SuLogEntry(policy);
if (version == 1) {
String action = intent.getStringExtra("action");
if (action == null) return;
switch (action) {
case "allow":
log.action = true;
break;
case "deny":
log.action = false;
break;
default:
return;
}
} else {
switch (intent.getIntExtra("policy", -1)) {
case Policy.ALLOW:
log.action = true;
break;
case Policy.DENY:
log.action = false;
break;
default:
return;
}
}
String message = mm.getString(log.action ?
R.string.su_allow_toast : R.string.su_deny_toast, policy.appName);
if (policy.notification && Data.suNotificationType == Const.Value.NOTIFICATION_TOAST)
Utils.toast(message, Toast.LENGTH_SHORT);
if (policy.logging) {
int toUid = intent.getIntExtra("to.uid", -1);
if (toUid < 0) return;
int pid = intent.getIntExtra("pid", -1);
if (pid < 0) return;
String command = intent.getStringExtra("command");
if (command == null) return;
log.toUid = toUid;
log.fromPid = pid;
log.command = command;
log.date = new Date();
mm.mDB.addLog(log);
}
}
}

View File

@@ -1,7 +1,5 @@
package com.topjohnwu.magisk.utils; package com.topjohnwu.magisk.utils;
import android.support.annotation.IntDef;
import com.topjohnwu.magisk.Data; import com.topjohnwu.magisk.Data;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -9,23 +7,24 @@ import java.lang.annotation.RetentionPolicy;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import androidx.annotation.IntDef;
public class Topic { public class Topic {
public static final int MAGISK_HIDE_DONE = 0; public static final int MAGISK_HIDE_DONE = 0;
public static final int RELOAD_ACTIVITY = 1; public static final int MODULE_LOAD_DONE = 1;
public static final int MODULE_LOAD_DONE = 2; public static final int REPO_LOAD_DONE = 2;
public static final int REPO_LOAD_DONE = 3; public static final int UPDATE_CHECK_DONE = 3;
public static final int UPDATE_CHECK_DONE = 4; public static final int SNET_CHECK_DONE = 4;
public static final int SNET_CHECK_DONE = 5; public static final int LOCALE_FETCH_DONE = 5;
public static final int LOCALE_FETCH_DONE = 6;
@IntDef({MAGISK_HIDE_DONE, RELOAD_ACTIVITY, MODULE_LOAD_DONE, REPO_LOAD_DONE, @IntDef({MAGISK_HIDE_DONE, MODULE_LOAD_DONE, REPO_LOAD_DONE,
UPDATE_CHECK_DONE, SNET_CHECK_DONE, LOCALE_FETCH_DONE}) UPDATE_CHECK_DONE, SNET_CHECK_DONE, LOCALE_FETCH_DONE})
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface TopicID {} public @interface TopicID {}
// We will not dynamically add topics, so use arrays instead of hash tables // We will not dynamically add topics, so use arrays instead of hash tables
private static Store[] topicList = new Store[7]; private static Store[] topicList = new Store[6];
public static void subscribe(Subscriber sub, @TopicID int... topics) { public static void subscribe(Subscriber sub, @TopicID int... topics) {
for (int topic : topics) { for (int topic : topics) {

View File

@@ -18,12 +18,13 @@ import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.container.Module; import com.topjohnwu.magisk.container.Module;
import com.topjohnwu.magisk.container.ValueSortedMap; import com.topjohnwu.magisk.container.ValueSortedMap;
import com.topjohnwu.magisk.services.UpdateCheckService;
import com.topjohnwu.superuser.io.SuFile; import com.topjohnwu.superuser.io.SuFile;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import a.n;
public class Utils { public class Utils {
public static int getPrefsInt(SharedPreferences prefs, String key, int def) { public static int getPrefsInt(SharedPreferences prefs, String key, int def) {
@@ -77,7 +78,7 @@ public class Utils {
if (mm.prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) { if (mm.prefs.getBoolean(Const.Key.CHECK_UPDATES, true)) {
if (scheduler.getAllPendingJobs().isEmpty() || if (scheduler.getAllPendingJobs().isEmpty() ||
Const.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) { Const.UPDATE_SERVICE_VER > mm.prefs.getInt(Const.Key.UPDATE_SERVICE_VER, -1)) {
ComponentName service = new ComponentName(mm, UpdateCheckService.class); ComponentName service = new ComponentName(mm, n.class);
JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service) JobInfo info = new JobInfo.Builder(Const.ID.UPDATE_SERVICE_ID, service)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true) .setPersisted(true)

View File

@@ -20,7 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@@ -54,42 +54,42 @@
android:textAppearance="@style/TextAppearance.AppCompat.Headline"/> android:textAppearance="@style/TextAppearance.AppCompat.Headline"/>
</LinearLayout> </LinearLayout>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/app_version_info" android:id="@+id/app_version_info"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_info_outline" app:icon="@drawable/ic_info_outline"
app:text="@string/app_version"/> app:text="@string/app_version"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/app_changelog" android:id="@+id/app_changelog"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_history" app:icon="@drawable/ic_history"
app:text="@string/app_changelog"/> app:text="@string/app_changelog"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/app_translators" android:id="@+id/app_translators"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_language" app:icon="@drawable/ic_language"
app:text="@string/app_translators"/> app:text="@string/app_translators"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/follow_twitter" android:id="@+id/follow_twitter"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_twitter" app:icon="@drawable/ic_twitter"
app:text="@string/follow_twitter"/> app:text="@string/follow_twitter"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/app_source_code" android:id="@+id/app_source_code"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_github" app:icon="@drawable/ic_github"
app:text="@string/app_source_code"/> app:text="@string/app_source_code"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/support_thread" android:id="@+id/support_thread"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -98,7 +98,7 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>

View File

@@ -20,7 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@@ -40,14 +40,14 @@
android:text="@string/donation" android:text="@string/donation"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"/> android:textAppearance="@style/TextAppearance.AppCompat.Headline"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/paypal" android:id="@+id/paypal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_paypal" app:icon="@drawable/ic_paypal"
app:text="PayPal"/> app:text="PayPal"/>
<com.topjohnwu.magisk.components.AboutCardRow <a.o
android:id="@+id/patreon" android:id="@+id/patreon"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -56,7 +56,7 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
@@ -24,7 +24,7 @@
</FrameLayout> </FrameLayout>
<android.support.design.widget.NavigationView <com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
@@ -32,4 +32,4 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
app:menu="@menu/drawer" /> app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/su_popup" android:id="@+id/su_popup"
tools:context=".superuser.RequestActivity" tools:context=".SuRequestActivity"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:minWidth="350dp" android:minWidth="350dp"

View File

@@ -7,7 +7,7 @@
android:orientation="vertical" android:orientation="vertical"
tools:context="com.topjohnwu.magisk.fragments.LogFragment"> tools:context="com.topjohnwu.magisk.fragments.LogFragment">
<android.support.design.widget.TabLayout <com.google.android.material.tabs.TabLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
@@ -17,10 +17,10 @@
android:elevation="4dp" android:elevation="4dp"
android:visibility="gone"> android:visibility="gone">
</android.support.design.widget.TabLayout> </com.google.android.material.tabs.TabLayout>
<android.support.v4.view.ViewPager <androidx.viewpager.widget.ViewPager
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/container"/> android:id="@+id/container"/>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"
@@ -18,7 +18,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/core_only_notice" android:id="@+id/core_only_notice"
style="?attr/cardStyle" style="?attr/cardStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -55,9 +55,9 @@
android:text="@string/settings_core_only_title" android:text="@string/settings_core_only_title"
android:textStyle="bold" /> android:textStyle="bold" />
</RelativeLayout> </RelativeLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
style="?attr/cardStyle" style="?attr/cardStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -141,9 +141,9 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/safetyNet_card" android:id="@+id/safetyNet_card"
style="?attr/cardStyle" style="?attr/cardStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -259,9 +259,9 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/install_option_card" android:id="@+id/install_option_card"
style="?attr/cardStyle" style="?attr/cardStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -308,9 +308,9 @@
android:text="@string/keep_dm_verity" /> android:text="@string/keep_dm_verity" />
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/install_button" android:id="@+id/install_button"
style="?attr/cardStyle" style="?attr/cardStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -361,9 +361,9 @@
</RelativeLayout> </RelativeLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/uninstall_button" android:id="@+id/uninstall_button"
style="?attr/cardStyle" style="?attr/cardStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -392,10 +392,10 @@
android:textSize="20sp" android:textSize="20sp"
android:textStyle="bold" /> android:textStyle="bold" />
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout" android:id="@+id/swipeRefreshLayout"
@@ -12,15 +12,15 @@ android:orientation="vertical">
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:dividerHeight="@dimen/card_divider_space" android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout> </LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -9,20 +9,20 @@
android:orientation="vertical"> android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator" android:id="@+id/coordinator"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:dividerHeight="@dimen/card_divider_space" android:dividerHeight="@dimen/card_divider_space"
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<TextView <TextView
android:id="@+id/empty_rv" android:id="@+id/empty_rv"
@@ -36,7 +36,7 @@
android:textStyle="italic" android:textStyle="italic"
android:visibility="gone" /> android:visibility="gone" />
<android.support.design.widget.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab" android:id="@+id/fab"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -47,6 +47,6 @@
tools:fabSize="normal" tools:fabSize="normal"
tools:pressedTranslationZ="12dp" /> tools:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</android.support.v4.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayout" <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:orientation="vertical"
@@ -23,13 +23,13 @@
android:textStyle="italic" android:textStyle="italic"
android:visibility="gone" /> android:visibility="gone" />
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:dividerHeight="@dimen/card_divider_space" android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout> </LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -18,11 +18,11 @@
android:textStyle="italic" android:textStyle="italic"
android:visibility="gone" /> android:visibility="gone" />
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:dividerHeight="@dimen/card_divider_space" android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout> </LinearLayout>

View File

@@ -17,11 +17,11 @@
android:textStyle="italic" android:textStyle="italic"
android:visibility="gone" /> android:visibility="gone" />
<android.support.v7.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:dividerHeight="@dimen/card_divider_space" android:dividerHeight="@dimen/card_divider_space"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" /> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout> </LinearLayout>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent" android:layout_width="fill_parent"
@@ -73,6 +73,6 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@@ -110,4 +110,4 @@
</RelativeLayout> </RelativeLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
style="?attr/cardStyle" style="?attr/cardStyle"
@@ -167,6 +167,6 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
style="?attr/cardStyle" style="?attr/cardStyle"
@@ -93,6 +93,6 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto" xmlns:card_view="http://schemas.android.com/apk/res-auto"
style="?attr/cardStyle" style="?attr/cardStyle"
@@ -140,6 +140,6 @@
</LinearLayout> </LinearLayout>
</android.support.v7.widget.CardView> </androidx.cardview.widget.CardView>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar android:id="@+id/toolbar" <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"

View File

@@ -1,9 +1,7 @@
### v5.9.0 ### 6.0.0
- No more on boot notifications - Update to latest AndroidX support library
- Support new mechanism for installing to inactive slot for OTAs on A/B devices - Fix crashes when online repos contain incomplete metadata
- Fix restore Magisk Manager settings on Android P - Optimize BootSigner to use as little memory as possible, prevent OutOfMemoryError
- Verify existing file checksums to prevent unnecessary re-downloads - Support new communication scheme between Magisk v17.2 and Magisk Manager
- Update SNET extension to use new Google API, fix "Invalid Response" errors - Enable excessive obfuscation to prevent APK analysis root detections (still not 100% obfuscated due to backwards compatibility with stable channel)
- Move fingerprint settings to magisk database to prevent the settings to be easily removed
- Fingerprint settings are now guarded with fingerprint authentications before it can get changed
- Prevent any files to be downloaded to `/sdcard/MagiskManager`

View File

@@ -10,11 +10,11 @@
<!--Status Fragment--> <!--Status Fragment-->
<string name="magisk_version_error">Magisk ist nicht installiert</string> <string name="magisk_version_error">Magisk ist nicht installiert</string>
<string name="checking_for_updates">Suche nach Aktualisierungen</string> <string name="checking_for_updates">Suche nach Aktualisierungen...</string>
<string name="magisk_update_available">Magisk %1$s ist verfügbar!</string> <string name="magisk_update_available">Magisk %1$s ist verfügbar!</string>
<string name="invalid_update_channel">Nicht valider Aktualisierungskanal</string> <string name="invalid_update_channel">Ungültiger Aktualisierungskanal</string>
<string name="safetyNet_check_text">SafetyNet-Status abfragen</string> <string name="safetyNet_check_text">SafetyNet-Status abfragen</string>
<string name="checking_safetyNet_status">Prüfe SafetyNet-Status</string> <string name="checking_safetyNet_status">Prüfe SafetyNet-Status...</string>
<string name="safetyNet_check_success">SafetyNet-Test erfolgreich</string> <string name="safetyNet_check_success">SafetyNet-Test erfolgreich</string>
<string name="safetyNet_api_error">SafetyNet API Fehler</string> <string name="safetyNet_api_error">SafetyNet API Fehler</string>
<string name="safetyNet_res_invalid">Die Antwort ist ungültig</string> <string name="safetyNet_res_invalid">Die Antwort ist ungültig</string>
@@ -27,7 +27,7 @@
<string name="install_magisk_title">Neueste Version: %1$s</string> <string name="install_magisk_title">Neueste Version: %1$s</string>
<string name="uninstall">Deinstallieren</string> <string name="uninstall">Deinstallieren</string>
<string name="uninstall_magisk_title">Magisk deinstallieren</string> <string name="uninstall_magisk_title">Magisk deinstallieren</string>
<string name="uninstall_magisk_msg">Alle Module werden deaktiviert/entfernt. Root wird entfernt und wenn die Daten nicht verschlüsselt sind, werden sie möglicherweise verschlüsselt.</string> <string name="uninstall_magisk_msg">Alle Module werden deaktiviert/entfernt. Root wird entfernt und möglicherweise werden Ihre Daten verschlüsseln, falls Ihre Daten derzeit nicht verschlüsselt sind.</string>
<string name="update">Aktualisierung %1$s</string> <string name="update">Aktualisierung %1$s</string>
<!--Module Fragment--> <!--Module Fragment-->
@@ -39,7 +39,7 @@
<string name="disable_file_created">Modul wird beim nächsten Neustart deaktiviert</string> <string name="disable_file_created">Modul wird beim nächsten Neustart deaktiviert</string>
<string name="disable_file_removed">Modul wird beim nächsten Neustart aktiviert</string> <string name="disable_file_removed">Modul wird beim nächsten Neustart aktiviert</string>
<string name="author">Erstellt von %1$s</string> <string name="author">Erstellt von %1$s</string>
<string name="reboot_recovery">Neustart in die Recovery</string> <string name="reboot_recovery">Neustart in das Recovery</string>
<string name="reboot_bootloader">Neustart in den Bootloader</string> <string name="reboot_bootloader">Neustart in den Bootloader</string>
<string name="reboot_download">Neustart in den Download-Modus</string> <string name="reboot_download">Neustart in den Download-Modus</string>
@@ -50,24 +50,25 @@
<string name="updated_on">Zuletzt aktualisiert: %1$s</string> <string name="updated_on">Zuletzt aktualisiert: %1$s</string>
<string name="sorting_order">Sortierung</string> <string name="sorting_order">Sortierung</string>
<string name="sort_by_name">Nach Namen sortiert</string> <string name="sort_by_name">Nach Namen sortiert</string>
<string name="sort_by_update">Nach Aktualisierung sortiert</string> <string name="sort_by_update">Nach Aktualisierungsdatum sortiert</string>
<!--Log Fragment--> <!--Log Fragment-->
<string name="menuSaveLog">Protokoll speichern</string> <string name="menuSaveLog">Log speichern</string>
<string name="menuReload">Log erneut laden</string> <string name="menuReload">Log erneut laden</string>
<string name="menuClearLog">Log löschen</string> <string name="menuClearLog">Log löschen</string>
<string name="logs_cleared">Log gelöscht</string> <string name="logs_cleared">Log gelöscht</string>
<string name="log_is_empty">Log ist leer</string> <string name="log_is_empty">Log ist leer</string>
<!--About Activity--> <!--About Activity-->
<string name="about">Über</string> <string name="about">Info</string>
<string name="app_changelog">Änderungen</string> <string name="app_changelog">Änderungsprotokoll</string>
<string name="translators">skalnet, c727, jenslody</string> <string name="translators">skalnet, c727, jenslody, SuperSandro2000</string>
<string name="app_version">Version</string> <string name="app_version">Version</string>
<string name="app_source_code">Quelltext</string> <string name="app_source_code">Quelltext</string>
<string name="donation">Spende</string> <string name="donation">Spenden</string>
<string name="app_translators">Übersetzer</string> <string name="app_translators">Übersetzer</string>
<string name="support_thread">Hilfeforum</string> <string name="support_thread">Hilfeforum</string>
<string name="follow_twitter">Folge mir auf Twitter</string>
<!--Toasts, Dialogs--> <!--Toasts, Dialogs-->
<string name="close">Schließen</string> <string name="close">Schließen</string>
@@ -75,12 +76,12 @@
<string name="repo_install_msg">Möchtest du %1$s installieren?</string> <string name="repo_install_msg">Möchtest du %1$s installieren?</string>
<string name="download">Herunterladen</string> <string name="download">Herunterladen</string>
<string name="reboot">Neustart</string> <string name="reboot">Neustart</string>
<string name="magisk_update_title">Neue Magisk-Aktualisierung verfügbar!</string> <string name="magisk_update_title">Neue Magisk Update verfügbar!</string>
<string name="settings_reboot_toast">Neustarten, um die Änderungen anzuwenden</string> <string name="settings_reboot_toast">Neustarten, um die Änderungen zu übernehmen</string>
<string name="release_notes">Änderungen</string> <string name="release_notes">Versionshinweise</string>
<string name="repo_cache_cleared">Repo-Cache gelöscht</string> <string name="repo_cache_cleared">Repo-Cache geleert</string>
<string name="process_error">Prozessfehler</string> <string name="process_error">Prozessfehler</string>
<string name="internal_storage">Die zip-Datei ist gespeichert unter:\n[Interner Speicher]%1$s</string> <string name="internal_storage">Die Zip-Datei ist gespeichert unter:\n[Interner Speicher]%1$s</string>
<string name="zip_download_title">Herunterladen</string> <string name="zip_download_title">Herunterladen</string>
<string name="zip_download_msg">Lade Zip-Datei herunter (%1$d%%) …</string> <string name="zip_download_msg">Lade Zip-Datei herunter (%1$d%%) …</string>
<string name="zip_process_title">Verarbeite</string> <string name="zip_process_title">Verarbeite</string>
@@ -88,30 +89,34 @@
<string name="manager_update_title">Aktualisierung für Magisk Manager verfügbar!</string> <string name="manager_update_title">Aktualisierung für Magisk Manager verfügbar!</string>
<string name="manager_download_install">Herunterladen und installieren</string> <string name="manager_download_install">Herunterladen und installieren</string>
<string name="dtbo_patched_title">DTBO wurde gepatched!</string> <string name="dtbo_patched_title">DTBO wurde gepatched!</string>
<string name="dtbo_patched_reboot">Magisk Manager hat dtbo.img gepatched, bitte Neustart durchführen</string> <string name="dtbo_patched_reboot">Magisk Manager hat dtbo.img gepatched, bitte neustarten</string>
<string name="magisk_updates">Magisk Aktualisierungen</string> <string name="magisk_updates">Magisk Update</string>
<string name="flashing">Flashing</string> <string name="flashing">Flashing</string>
<string name="hide_manager_toast">Verberge Magisk Manager…</string> <string name="hide_manager_toast">Verberge Magisk Manager…</string>
<string name="hide_manager_toast2">Dies könnte einige Zeit in Anspruch nehmen…</string> <string name="hide_manager_toast2">Das könnte einige Zeit dauern...</string>
<string name="hide_manager_fail_toast">Verbergen von Magisk Manager fehlgeschlagen…</string> <string name="hide_manager_fail_toast">Verbergen von Magisk Manager fehlgeschlagen…</string>
<string name="download_zip_only">Zip-Datei nur herunterladen</string> <string name="open_link_failed_toast">Es wurde keine Anwendung gefunden, um diesen Link zu öffnen...</string>
<string name="download_zip_only">Nur Zip-Datei herunterladen</string>
<string name="patch_boot_file">Boot-Image-Datei patchen</string> <string name="patch_boot_file">Boot-Image-Datei patchen</string>
<string name="direct_install">Direkt installieren (empfohlen)</string> <string name="direct_install">Direkt installieren (empfohlen)</string>
<string name="install_inactive_slot">Installiere auf inaktiven Slot (Nach OTA)</string>
<string name="warning">Warnung</string>
<string name="install_inactive_slot_msg">Dein Gerät wird GEZWUNGEN in den aktuell inaktiven Slot zu starten, nachdem nach dem ein Neustart durchgeführt wurde!\nBenutze diese Option nur, nachdem das OTA beendet wurde.\nFortsetzen?</string>
<string name="select_method">Methode auswählen</string> <string name="select_method">Methode auswählen</string>
<string name="no_boot_file_patch_support">Magisk Zielversion unterstützt das Patchen des Boot-Images nicht</string> <string name="no_boot_file_patch_support">Magisk Zielversion unterstützt das Patchen von Boot-Images nicht</string>
<string name="boot_file_patch_msg">Selektiere das originale Boot image dump im Format .img oder .img.tar</string> <string name="boot_file_patch_msg">Wähle das original Boot-Image-Dump im Format .img oder .img.tar</string>
<string name="complete_uninstall">Komplette Deinstallation</string> <string name="complete_uninstall">Komplette Deinstallation</string>
<string name="restore_img">Images wiederherstellen</string> <string name="restore_img">Images wiederherstellen</string>
<string name="restore_img_msg">Wiederherstellen...</string> <string name="restore_img_msg">Wiederherstellen...</string>
<string name="restore_done">Wiederherstellung durchgeführt!</string> <string name="restore_done">Wiederherstellung erfolgreich!</string>
<string name="restore_fail">Kein Original Backup vorhanden!</string> <string name="restore_fail">Kein Original Backup vorhanden!</string>
<string name="proprietary_title">Lade proprietären Code herunter</string> <string name="proprietary_title">Lade proprietären Code herunter</string>
<string name="proprietary_notice">Magisk Manager ist FOSS und enthält keinen proprietären SafetyNet API Code von Google. Magisk Manager erlauben eine Erweiterung (enthält GoogleApiClient) für SafetyNet-Checks herunterzuladen?</string> <string name="proprietary_notice">Magisk Manager ist FOSS und enthält keinen proprietären SafetyNet API Code von Google. Magisk Manager erlauben eine Erweiterung (enthält GoogleApiClient) für SafetyNet-Checks herunterzuladen?</string>
<string name="su_db_corrupt">Datenbank für SU ist fehlerhaft, es wird eine neue erstellt</string> <string name="su_db_corrupt">SU-Datenbank ist fehlerhaft, es wird eine neue erstellt</string>
<string name="setup_done">Einrichtung abgeschlossen</string> <string name="setup_done">Einrichtung abgeschlossen</string>
<string name="setup_fail">Einrichtung fehlgeschlagen</string> <string name="setup_fail">Einrichtung fehlgeschlagen</string>
<string name="env_fix_title">Zusätzliche Einrichtung erforderlich</string> <string name="env_fix_title">Zusätzliche Einrichtung erforderlich</string>
<string name="env_fix_msg">Um Magisk ordnungsgemäß zu nutzen, benötigt das Geräte eine zusätzliche Einrichtung. Magisk Einrichtungs-zip wird heruntergeladen, fortsetzen?</string> <string name="env_fix_msg">Ihr Gerät benötigt zusätzliche Einrichtung, damit Magisk ordnungsgemäß funktioniert. Es wird eine Magisk-Installations-Zip wird heruntergeladen, fortfahren?</string>
<string name="setup_title">Zusätzliche Einrichtung</string> <string name="setup_title">Zusätzliche Einrichtung</string>
<string name="setup_msg">Umgebungseinrichtung läuft…</string> <string name="setup_msg">Umgebungseinrichtung läuft…</string>
@@ -119,12 +124,12 @@
<string name="settings_general_category">Allgemein</string> <string name="settings_general_category">Allgemein</string>
<string name="settings_dark_theme_title">Dunkles Theme</string> <string name="settings_dark_theme_title">Dunkles Theme</string>
<string name="settings_dark_theme_summary">Dunkles Theme aktivieren</string> <string name="settings_dark_theme_summary">Dunkles Theme aktivieren</string>
<string name="settings_clear_cache_title">Repo-Cache löschen</string> <string name="settings_clear_cache_title">Repo-Cache leeren</string>
<string name="settings_clear_cache_summary">Löscht die zwischengespeicherten Informationen der Online-Repos. Erzwingt eine Online-Aktualisierung</string> <string name="settings_clear_cache_summary">Löscht die zwischengespeicherten Informationen des Online-Repos. Erzwingt eine Aktualisierung</string>
<string name="settings_hide_manager_title">Magisk Manager verbergen</string> <string name="settings_hide_manager_title">Magisk Manager verbergen</string>
<string name="settings_hide_manager_summary">Magisk Manager mit zufälligem Paketnamen neu packen</string> <string name="settings_hide_manager_summary">Magisk Manager mit zufälligem Paketnamen neu packen</string>
<string name="settings_restore_manager_title">Stelle Magisk Manager wieder her</string> <string name="settings_restore_manager_title">Magisk Manager wiederherstellen</string>
<string name="settings_restore_manager_summary">Stelle Magisk Manager mit ursprünglichem Paket wieder her</string> <string name="settings_restore_manager_summary">Stellt Magisk Manager mit ursprünglichem Paketnamen wieder her</string>
<string name="language">Sprache</string> <string name="language">Sprache</string>
<string name="system_default">(Systemstandard)</string> <string name="system_default">(Systemstandard)</string>
<string name="settings_update">Aktualisierungs-Einstellungen</string> <string name="settings_update">Aktualisierungs-Einstellungen</string>
@@ -134,13 +139,13 @@
<string name="settings_update_stable">Stabil</string> <string name="settings_update_stable">Stabil</string>
<string name="settings_update_beta">Beta</string> <string name="settings_update_beta">Beta</string>
<string name="settings_update_custom">Benutzerdefiniert</string> <string name="settings_update_custom">Benutzerdefiniert</string>
<string name="settings_update_custom_msg">Gebe eine benutzerdefinierte URL ein</string> <string name="settings_update_custom_msg">Gib eine benutzerdefinierte URL ein</string>
<string name="settings_boot_format_title">Ausgabeformat des gepatchten Boot-Images</string> <string name="settings_boot_format_title">Ausgabeformat des gepatchten Boot-Images</string>
<string name="settings_boot_format_summary">Wähle das Ausgabeformat des gepatchten Boot-Images.\nWähle .img, um mit \"fastboot/download mode\" zu flashen; wähle .img.tar zum Flashen mit ODIN.</string> <string name="settings_boot_format_summary">Wähle das Ausgabeformat des gepatchten Boot-Images.\nWähle .img, um mit \"fastboot/download mode\" zu flashen; wähle .img.tar zum Flashen mit ODIN.</string>
<string name="settings_core_only_title">Nur Kernfunktionen</string> <string name="settings_core_only_title">Nur Kernfunktionen</string>
<string name="settings_core_only_summary">Aktiviert lediglich die Kernfunktionen, Module werden nicht geladen. MagiskSU, Magisk Hide und Systemless hosts bleiben weiterhin aktiv</string> <string name="settings_core_only_summary">Aktiviert lediglich die Kernfunktionen, Module werden nicht geladen. MagiskSU, Magisk Hide und Systemless hosts bleiben weiterhin aktiv</string>
<string name="settings_magiskhide_summary">Versteckt Magisk vor diversen Entdeckungsmethoden</string> <string name="settings_magiskhide_summary">Versteckt Magisk vor diversen Entdeckungsmethoden</string>
<string name="settings_hosts_title">Systemlose hosts-Datei</string> <string name="settings_hosts_title">Systemlose Hosts-Datei</string>
<string name="settings_hosts_summary">Systemlose Unterstützung für Werbeblocker</string> <string name="settings_hosts_summary">Systemlose Unterstützung für Werbeblocker</string>
<string name="settings_su_app_adb">Apps und ADB</string> <string name="settings_su_app_adb">Apps und ADB</string>
@@ -160,6 +165,7 @@
<string name="settings_su_reauth_summary">Superuser-Zugriff nach App-Aktualisierung erneut abfragen</string> <string name="settings_su_reauth_summary">Superuser-Zugriff nach App-Aktualisierung erneut abfragen</string>
<string name="settings_su_fingerprint_title">Aktiviere Authentifizierung durch Fingerabdruck</string> <string name="settings_su_fingerprint_title">Aktiviere Authentifizierung durch Fingerabdruck</string>
<string name="settings_su_fingerprint_summary">Fingerabdrucksensor benutzen um Superuser-Anfragen zu erlauben</string> <string name="settings_su_fingerprint_summary">Fingerabdrucksensor benutzen um Superuser-Anfragen zu erlauben</string>
<string name="auth_fingerprint">Authentifiziere Fingerabdruck</string>
<string name="multiuser_mode">Mehrbenutzermodus</string> <string name="multiuser_mode">Mehrbenutzermodus</string>
<string name="settings_owner_only">Nur der Gerätebesitzer</string> <string name="settings_owner_only">Nur der Gerätebesitzer</string>
@@ -168,15 +174,15 @@
<string name="owner_only_summary">Nur der Besitzer hat Root-Zugriff</string> <string name="owner_only_summary">Nur der Besitzer hat Root-Zugriff</string>
<string name="owner_manage_summary">Nur der Besitzer verwaltet den Root-Zugriff und erhält Zugriffs-Anfragen</string> <string name="owner_manage_summary">Nur der Besitzer verwaltet den Root-Zugriff und erhält Zugriffs-Anfragen</string>
<string name="user_indepenent_summary">Jeder Nutzer hat seine eingenen Root-Regeln</string> <string name="user_indepenent_summary">Jeder Nutzer hat seine eingenen Root-Regeln</string>
<string name="multiuser_hint_owner_request">Eine Anfrage wurde an den Gerätebesitzer gesendet. Bitte wechsle zum Bersitzerkonto und gewähre die Rechte</string> <string name="multiuser_hint_owner_request">Eine Anfrage wurde an den Gerätebesitzer gesendet. Bitte wechsel zum Bersitzerkonto und gewähre die Rechte.</string>
<string name="mount_namespace_mode">Namensraum-Modus</string> <string name="mount_namespace_mode">Mount-Namespace-Modus</string>
<string name="settings_ns_global">Globaler Namensraum</string> <string name="settings_ns_global">Globaler Namespace</string>
<string name="settings_ns_requester">Geerbter Namensraum</string> <string name="settings_ns_requester">Geerbter Namespace</string>
<string name="settings_ns_isolate">Isolierter Namensraum</string> <string name="settings_ns_isolate">Isolierter Namespace</string>
<string name="global_summary">Alle Root-Sitzungen benutzen den global angelegten Namensraum</string> <string name="global_summary">Alle Root-Sitzungen benutzen den global angelegten Namespace</string>
<string name="requester_summary">Root-Sitzungen erben den Namensraum des Abfragenden</string> <string name="requester_summary">Root-Sitzungen erben den Namespace des Abfragenden</string>
<string name="isolate_summary">Jede Root-Sitzung hat ihren isolierten Namensraum</string> <string name="isolate_summary">Jede Root-Sitzung hat ihren isolierten Namespace</string>
<string name="android_o_not_support">Android 8.0+ wird nicht unterstützt</string> <string name="android_o_not_support">Android 8.0+ wird nicht unterstützt</string>
<string name="disable_fingerprint">Keine Fingerabdrücke gespeichert oder keine Geräteunterstützung</string> <string name="disable_fingerprint">Keine Fingerabdrücke gespeichert oder keine Geräteunterstützung</string>

View File

@@ -68,6 +68,7 @@
<string name="donation">Dons</string> <string name="donation">Dons</string>
<string name="app_translators">Traducteurs de l\'application</string> <string name="app_translators">Traducteurs de l\'application</string>
<string name="support_thread">Fil d\'assistance</string> <string name="support_thread">Fil d\'assistance</string>
<string name="follow_twitter">Me suivre sur Twitter</string>
<!--Toasts, Dialogs--> <!--Toasts, Dialogs-->
<string name="close">Fermer</string> <string name="close">Fermer</string>
@@ -89,11 +90,12 @@
<string name="manager_download_install">Appuyer pour télécharger et installer</string> <string name="manager_download_install">Appuyer pour télécharger et installer</string>
<string name="dtbo_patched_title">DTBO a été patché!</string> <string name="dtbo_patched_title">DTBO a été patché!</string>
<string name="dtbo_patched_reboot">Le Gestionnaire Magisk a vient de patcher dtbo.img, merci de redémarrer</string> <string name="dtbo_patched_reboot">Le Gestionnaire Magisk a vient de patcher dtbo.img, merci de redémarrer</string>
<string name="magisk_updates">Mises à jours Magisk</string> <string name="magisk_updates">Mises à jours Magisk</string>
<string name="flashing">Flashage</string> <string name="flashing">Installation</string>
<string name="hide_manager_toast">Masquage du Gestionnaire Magisk…</string> <string name="hide_manager_toast">Masquer le Gestionnaire Magisk…</string>
<string name="hide_manager_toast2">Cela pourrait prendre un certain temps …</string> <string name="hide_manager_toast2">Cela pourrait prendre un certain temps …</string>
<string name="hide_manager_fail_toast">Masquage du Gestionnaire Magisk échoué…</string> <string name="hide_manager_fail_toast">Masquage du Gestionnaire Magisk échoué…</string>
<string name="open_link_failed_toast">Aucune application trouvée pour ouvrir le lien…</string>
<string name="download_zip_only">Uniquement télécharger le zip</string> <string name="download_zip_only">Uniquement télécharger le zip</string>
<string name="patch_boot_file">Patch Fichier Image Démarrage</string> <string name="patch_boot_file">Patch Fichier Image Démarrage</string>
<string name="direct_install">Installation directe (Recommendée)</string> <string name="direct_install">Installation directe (Recommendée)</string>
@@ -110,7 +112,7 @@
<string name="restore_fail">Le sauvegarde par défaut n\'existe pas!</string> <string name="restore_fail">Le sauvegarde par défaut n\'existe pas!</string>
<string name="proprietary_title">Télécharger Code Propriétaire</string> <string name="proprietary_title">Télécharger Code Propriétaire</string>
<string name="proprietary_notice">Magisk Manager est Libre, il ne contient pas le code API SafetyNet propriétaire de Google. \ N \ nAutorisez vous le Gestionnaire Magisk à télécharger une extension (contenant GoogleApiClient) pour les contrôles SafetyNet? </string> <string name="proprietary_notice">Magisk Manager est Libre, il ne contient pas le code API SafetyNet propriétaire de Google. \ N \ nAutorisez vous le Gestionnaire Magisk à télécharger une extension (contenant GoogleApiClient) pour les contrôles SafetyNet? </string>
<string name = "su_db_corrupt"> La base de données SU est corrompue, une nouvelle base de donnée va être re-créé</string> <string name = "su_db_corrupt"> La base de données SU est corrompue, une nouvelle base de donnée va être re-créée</string>
<string name="setup_done">Installation terminée</string> <string name="setup_done">Installation terminée</string>
<string name="setup_fail">Échec de l\'installation</string> <string name="setup_fail">Échec de l\'installation</string>
<string name="env_fix_title">Installation additionnelle requise</string> <string name="env_fix_title">Installation additionnelle requise</string>
@@ -156,11 +158,11 @@
<string name="settings_su_request_60">60 secondes</string> <string name="settings_su_request_60">60 secondes</string>
<string name="superuser_access">Accès Superuser</string> <string name="superuser_access">Accès Superuser</string>
<string name="auto_response">Réponse automatique</string> <string name="auto_response">Réponse automatique</string>
<string name="request_timeout">Délai de requête</string> <string name="request_timeout">Délai d\'attente de la demande</string>
<string name="superuser_notification">Notification Superutilisateur</string> <string name="superuser_notification">Notification Superutilisateur</string>
<string name="request_timeout_summary">%1$s secondes</string> <string name="request_timeout_summary">%1$s secondes</string>
<string name="settings_su_reauth_title">Réauthentifier après la mise à niveau</string> <string name="settings_su_reauth_title">Authentifier à nouveau après la mise à niveau</string>
<string name="settings_su_reauth_summary">Réauthentifier les autorisations superutilisateur après une mise à jour de l\'application</string> <string name="settings_su_reauth_summary">Authentifier à nouveau les autorisations superutilisateur après une mise à jour de l\'application</string>
<string name="settings_su_fingerprint_title">Activer l\'authentification par empreinte digitale</string> <string name="settings_su_fingerprint_title">Activer l\'authentification par empreinte digitale</string>
<string name="settings_su_fingerprint_summary">Utiliser le scanner d\'empreintes digitales pour autoriser les demandes superutilisateur</string> <string name="settings_su_fingerprint_summary">Utiliser le scanner d\'empreintes digitales pour autoriser les demandes superutilisateur</string>
<string name="auth_fingerprint">Authentifier l\'empreinte digitale</string> <string name="auth_fingerprint">Authentifier l\'empreinte digitale</string>
@@ -181,7 +183,7 @@
<string name="global_summary">Toutes les sessions racines utilisent l\'espace de noms de montage global</string> <string name="global_summary">Toutes les sessions racines utilisent l\'espace de noms de montage global</string>
<string name="requester_summary">Les sessions racines hériteront de l\'espace de noms de son demandeur</string> <string name="requester_summary">Les sessions racines hériteront de l\'espace de noms de son demandeur</string>
<string name="isolate_summary">Chaque session racine aura son propre espace de noms isolé</string> <string name="isolate_summary">Chaque session racine aura son propre espace de noms isolé</string>
<string name="android_o_not_support">Android 8.0+ n\'est pas supporté</string> <string name="android_o_not_support">Android 8.0+ non supporté</string>
<string name="disable_fingerprint">Aucune empreinte digitale n\'a été définie ou aucun support de périphérique</string> <string name="disable_fingerprint">Aucune empreinte digitale n\'a été définie ou aucun support de périphérique</string>
<!--Superuser--> <!--Superuser-->

View File

@@ -67,6 +67,7 @@
<string name="donation">Donasi</string> <string name="donation">Donasi</string>
<string name="app_translators">Penerjemah</string> <string name="app_translators">Penerjemah</string>
<string name="support_thread">Thread dukungan</string> <string name="support_thread">Thread dukungan</string>
<string name="follow_twitter">Ikuti saya di Twitter</string>
<!--Toasts, Dialogs--> <!--Toasts, Dialogs-->
<string name="close">Tutup</string> <string name="close">Tutup</string>
@@ -161,6 +162,7 @@
<string name="settings_su_reauth_summary">Otentikasi ulang izin superuser setelah pembaruan sebuah aplikasi</string> <string name="settings_su_reauth_summary">Otentikasi ulang izin superuser setelah pembaruan sebuah aplikasi</string>
<string name="settings_su_fingerprint_title">Aktifkan Otentikasi Sidik Jari</string> <string name="settings_su_fingerprint_title">Aktifkan Otentikasi Sidik Jari</string>
<string name="settings_su_fingerprint_summary">Gunakan pemindai sidik jari untuk mengizinkan permintaan superuser</string> <string name="settings_su_fingerprint_summary">Gunakan pemindai sidik jari untuk mengizinkan permintaan superuser</string>
<string name="auth_fingerprint">Otentikasi Sidik Jari</string>
<string name="multiuser_mode">Mode Multipengguna</string> <string name="multiuser_mode">Mode Multipengguna</string>
<string name="settings_owner_only">Pemilik Perangkat Saja</string> <string name="settings_owner_only">Pemilik Perangkat Saja</string>

View File

@@ -6,7 +6,7 @@
<string name="superuser">Superuser</string> <string name="superuser">Superuser</string>
<string name="log">Záznamy</string> <string name="log">Záznamy</string>
<string name="settings">Nastavenia</string> <string name="settings">Nastavenia</string>
<string name="install">Inštalácia</string> <string name="install">Inštalovať</string>
<!--Status Fragment--> <!--Status Fragment-->
<string name="magisk_version_error">Magisk nie je nainštalovaný</string> <string name="magisk_version_error">Magisk nie je nainštalovaný</string>
@@ -74,7 +74,7 @@
<string name="repo_install_title">Nainštalovať %1$s</string> <string name="repo_install_title">Nainštalovať %1$s</string>
<string name="repo_install_msg">Chcete teraz nainštalovať %1$s?</string> <string name="repo_install_msg">Chcete teraz nainštalovať %1$s?</string>
<string name="download">Stiahnuť</string> <string name="download">Stiahnuť</string>
<string name="reboot">Reštartovať</string> <string name="reboot">Reštart</string>
<string name="magisk_update_title">Nová aktualizácia Magisk!</string> <string name="magisk_update_title">Nová aktualizácia Magisk!</string>
<string name="settings_reboot_toast">Pre aplikovanie nastavení je potrebný reštart</string> <string name="settings_reboot_toast">Pre aplikovanie nastavení je potrebný reštart</string>
<string name="release_notes">Poznámky k vydaniu</string> <string name="release_notes">Poznámky k vydaniu</string>

View File

@@ -68,6 +68,7 @@
<string name="donation">Підтримати проект</string> <string name="donation">Підтримати проект</string>
<string name="app_translators">Перекладачі</string> <string name="app_translators">Перекладачі</string>
<string name="support_thread">Сторінка підтримки</string> <string name="support_thread">Сторінка підтримки</string>
<string name="follow_twitter">Читати мене в Twitter</string>
<!--Toasts, Dialogs--> <!--Toasts, Dialogs-->
<string name="close">Закрити</string> <string name="close">Закрити</string>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:tools="http://schemas.android.com/tools"
tools:discard="@raw/busybox_arm,@raw/busybox_x86" />

Some files were not shown because too many files have changed in this diff Show More