├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── encodings.xml
├── gradle.xml
├── markdown-exported-files.xml
├── markdown-navigator.xml
├── misc.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE
├── README.md
├── README_zh.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── xposed_init
│ ├── java
│ └── com
│ │ └── xposed
│ │ └── miuianesthetist
│ │ ├── BaseXposedHookLoadPackage.java
│ │ ├── DisableSecurityCheck.java
│ │ └── XposedHelpersWraper.java
│ └── res
│ ├── values-en
│ └── strings.xml
│ ├── values-zh-rCN
│ └── strings.xml
│ ├── values-zh-rTW
│ └── strings.xml
│ └── values
│ └── strings.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/markdown-exported-files.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Neo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MIUI Anesthetist
2 | Carry out surgical strikes against MIUI. This module is committed to remove the limitations of MIUI, allowing you to enter the God mode of MIUI.
3 |
4 | [中文版](https://github.com/neoblackxt/MIUIAnesthetist/blob/master/README_zh.md)
5 |
6 | ## FEATURES
7 | Disable MIUI integrity check during boot to prevent boot-loop, so that you can safely force delete System Updater and other system apps.
8 |
9 | Remove limit for disabling some packages and prevent some packages from re-enabling during reboot.(For some ultra-sticky system apps we have to **reboot** after disabling them to take effect)
10 |
11 | Prevent MI Market from hijacking Google Play on MIUI China ROMs. Thanks to & for the inspiration from: 跟悟空扯关系@CoolApk 去除MIUI强制调用小米应用商店(非改build)、ccat3z@github 我不要小米应用市场
12 |
13 | Remove limit for third-party launchers on MIUI China ROMs. Thanks to & for the inspiration from: tianma8023@github FuckMiui
14 |
15 | Allow users to use Security - Manage apps to disable system apps.
16 |
17 | Remove limit for installing system apps from unofficial channels on MIUI China ROMs.
18 |
19 | ## USAGE
20 | Install and enable this Xposed module, then reboot.
21 |
22 | Freely disable the packages which you don't need. (These packages will be keep disabled after updating system)
23 |
24 | To remove system apps, use [MIUI Anesthetist Helper Magisk module](https://github.com/neoblackxt/MIUIAnesthetist/releases/download/v2.0/MIUIAnesthetistHelperMagiskModule.zip)(hereinafter referred to as "helper module") in release, and [Magisk Manager for Recovery Mode](https://github.com/Magisk-Modules-Repo/mm)(hereinafter referred to as "mm") is also needed. (These packages will be kept removed after updating system)
25 | Modify `install.sh` file in helper module: add the directory paths which the apps you want to remove are located in to `REPLACE=""`, one path per line, there is a good example in a couple of lines above in this file. Once finished, you can add it to [Magisk Manager](https://github.com/topjohnwu/Magisk/releases) or install it in recovery mode.
26 | This helper module only removes MiuiSuperMarket by default, it's useless for MIUI global edition users, so remove that line.
27 | You may share your modified and tested helper modules with you friends. :)
28 |
29 | Learn more: [Magisk guides](https://topjohnwu.github.io/Magisk/guides.html#remove-folders)
30 |
31 | ## NOTICE
32 | The toolchain is as: Magisk -> (Riru-Core) -> (Riru-Ed)Xposed -> MIUI Anesthetist
33 |
34 | You should flash Magisk immediately as soon as you update system in recovery mode to ensure the toolchain is working.
35 |
36 | If this module is disabled by accident, its magic will disappear and then your phone may boot-loop. (See **RESCUE**)
37 | The case can be:
38 | ①This Xposed module is disabled
39 | ②Xposed framework is disabled
40 | ③Magisk which Xposed relies on is disabled
41 | ④After reinstalling or updating this Xposed module, Xposed installer doesn't detect its update.(You have to disable it and then re-enable it manually in Xposed module list)
42 |
43 | Some system apps are Android core programs, they should **never** be disabled or removed. If you have no idea about a system app, you should Google it first and think twice.
44 |
45 | ## RESCUE
46 | If you have disabled some system apps, remove or rename `/data/system/users/0/package-restrictions.xml` file to reset disabling app settings.
47 |
48 | If you have removed some system apps, disable the helper module using mm to recover all system apps. BTW, you'd better read its [README](https://github.com/Magisk-Modules-Repo/mm/blob/master/README.md) to know its usage early.
49 |
50 | If you have **really** removed some system app files from ROM, flash ROM (**NOT** need to wipe `/data`).
51 |
52 | **Advanced:**
53 | ①In `/data/system/users/0/package-restrictions.xml` file, the `enabled` attribute determines if a package is disabled. `enabled=3` means it is disabled, and remove `enabled=3` to enable it.
54 | ②Magisk determines if a Magisk module is enabled by looking for `/data/adb/modules//disable` file. If it exists, it means the module is disabled.(Some old versions don't support this)
55 | ③(Ed)Xposed's config file is `/data/user_de/0/<(Ed)Xposed-installer(manager)-package-name>/conf/modules.list` file, its format is Xposed module apk files' absolute paths, one path per line, like `/data/app/-/base.apk`
56 |
57 | ## MISCELLANEOUS
58 | Help me translate or optimize this README if you like.
59 |
--------------------------------------------------------------------------------
/README_zh.md:
--------------------------------------------------------------------------------
1 | # MIUI麻醉师
2 | 对MIUI进行外科手术式打击。此模块致力于解除MIUI的各种功能限制,让你对MIUI开启上帝模式。
3 |
4 | [For English users](https://github.com/neoblackxt/MIUIAnesthetist/blob/master/README.md)
5 |
6 | ## 功能特性
7 | 禁止MIUI系统启动时检查自身完整性,防止删除系统应用后出现循环重启问题(如小米应用商店、系统更新等)。
8 |
9 | 解除MIUI系统部分系统应用、组件不能被冻结的限制,并且避免被冻结的应用在重启后自动解冻。(对于一些特别顽固的应用需要冻结后再**重启**才能生效,全球上网必须在MConnService(VsimCore.apk)冻结之后才能成功冻结)
10 |
11 | 禁止MIUI系统将小米应用商店自动设置为默认应用商店劫持Google Play应用商店。~~(其实就是去你大爷的小米应用商店)~~ 感谢&启发自:跟悟空扯关系@酷安网 [去除MIUI强制调用小米应用商店(非改build)](https://www.coolapk.com/feed/8492730?shareKey=MjM2ODkyMTI5Zjg4NWNlZDJhMzI~)、ccat3z@github 我不要小米应用市场
12 |
13 | 解除MIUI系统对于未认证的第三方桌面的限制。感谢&启发自:tianma8023@github [糙米](https://github.com/neoblackxt/FuckMiui)
14 |
15 | 开启 安全中心 -> 应用管理 的停用系统应用的功能。
16 |
17 | 解除无法从非官方渠道安装系统应用的限制。
18 |
19 | ## 使用方法
20 | 安装并启用此Xposed模块,重启系统。
21 |
22 | 使用太极框架的用户须安装[太极Magisk](https://github.com/taichi-framework/TaiChi/wiki/taichi-magisk-zh)开启太极阳,按需添加应用: 应用包管理组件、安全中心、设置。
23 |
24 | 用任何你喜欢的工具/方式冻结你需要冻结的应用。即使安装系统更新,应用也会保持被冻结的状态。
25 |
26 | 使用release中的[MIUI麻醉师助手Magisk模块](https://github.com/neoblackxt/MIUIAnesthetist/releases/download/v2.0/MIUIAnesthetistHelperMagiskModule.zip)(以下简称助手模块)移除你想要移除的系统应用,并安装[mm管理器](https://github.com/Magisk-Modules-Repo/mm)。即使安装系统更新,应用也会保持被移除的状态。
27 | 此助手模块默认只移除小米应用商店。修改此模块中的`install.sh`文件,将你想要移除的应用的所在目录填写在`REPLACE=""`中,一行一个,格式参照文件中上面几行的例子。修改完成后在[Magisk Manager](https://github.com/topjohnwu/Magisk/releases)中安装它或在recovery模式下刷入它。
28 | 你可以将你修改过的并且测试过没有问题的助手模块分享给你网络社区中的朋友们 :)
29 |
30 |
31 | 更多信息:[Magisk模块指南](https://topjohnwu.github.io/Magisk/guides.html#remove-folders)
32 |
33 | ## 注意事项
34 | 工具链是这样的:Magisk -> (Riru-Core) -> (Riru-Ed)Xposed -> MIUI Anesthetist
35 |
36 | 通过recovery模式升级系统后,应立即刷入Magisk,然后才能开机,以确保工具链有效。
37 |
38 | 一旦因误操作致使工具链断裂,此模块功能失效,手机可能无法开机进入系统。解决方案见下方的**救援**部分。
39 | 可能致使工具链断裂的情况有:
40 | ①禁用此Xposed模块
41 | ②禁用Xposed框架
42 | ③禁用Xposed框架依附的Magisk
43 | ④重新安装/版本升级此模块后,Xposed Installer没检测到此模块更新(此时必须手动关闭再打开才能再次启用)
44 |
45 | 有一些系统应用是安卓的核心程序,这些应用是绝对**不可以**被冻结或者删除的。如果你不了解某个应用,你应该先谷歌一下,三思而后行。
46 |
47 | ## 救援
48 | 如果因冻结系统应用而无法开机,删除或重命名`/data/system/users/0/package-restrictions.xml`文件可以重置应用冻结设置。
49 | 操作方法:
50 | ①在TWRP recovery的 高级 -> 文件管理 中找到该文件删除。
51 | ②在recovery终端中执行命令`rm /data/system/users/0/package-restrictions.xml`。
52 | ③用电脑连接recovery模式中的手机,在`cmd`中执行`adb shell`,然后`rm /data/system/users/0/package-restrictions.xml`。
53 | 刷机**不会**有任何帮助,擦除`/data`分区是可行的但没必要,因为那样会丢失除了`/sdcard`之外的所有数据。
54 |
55 | 如果因删除系统应用无法开机,在recovery模式用mm管理器禁用助手模块即可恢复所有系统应用。你最好提前阅读它的[使用说明](https://github.com/Magisk-Modules-Repo/mm/blob/master/README.md)。
56 |
57 | 如果你没有使用助手模块而是用文件管理器彻底删掉了某个系统应用,可通过刷机恢复(**不必**清除`/data`分区)。
58 |
59 | **高级:**
60 | ①`/data/system/users/0/package-restrictions.xml`文件中有关冻结的元素属性是`enabled`,`enabled=3`为冻结,删除`enabled=3`即解冻。
61 | ②Magisk配置模块是否启用的方式是查看`/data/adb/modules//disable`文件是否存在,存在为禁用,反之为启用(旧版Magisk不支持此方式)
62 | ③(Ed)Xposed启用模块的配置文件为`/data/user_de/0/<(Ed)Xposed-installer(manager)-package-name>/conf/modules.list`,配置格式为Xposed模块apk文件的绝对路径,每行一个,形如`/data/app/-/base.apk`
63 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | defaultConfig {
6 | applicationId 'com.xposed.miuianesthetist'
7 | minSdkVersion 14
8 | targetSdkVersion 29
9 | versionCode 4
10 | versionName '3.0'
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | manifestPlaceholders = [:]
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility = '1.8'
22 | targetCompatibility = '1.8'
23 | }
24 | buildToolsVersion = '29.0.1'
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | compileOnly 'de.robv.android.xposed:api:53'
30 | }
31 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
10 |
13 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | com.xposed.miuianesthetist.DisableSecurityCheck
--------------------------------------------------------------------------------
/app/src/main/java/com/xposed/miuianesthetist/BaseXposedHookLoadPackage.java:
--------------------------------------------------------------------------------
1 | package com.xposed.miuianesthetist;
2 |
3 | import de.robv.android.xposed.IXposedHookLoadPackage;
4 | import de.robv.android.xposed.IXposedHookZygoteInit;
5 |
6 | import static com.xposed.miuianesthetist.XposedHelpersWraper.setTAG;
7 |
8 |
9 | public abstract class BaseXposedHookLoadPackage implements IXposedHookLoadPackage, IXposedHookZygoteInit {
10 | protected Boolean iib;
11 | static {
12 | setTAG("miuianesthetist");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/xposed/miuianesthetist/DisableSecurityCheck.java:
--------------------------------------------------------------------------------
1 | package com.xposed.miuianesthetist;
2 |
3 | import android.app.Activity;
4 | import android.content.ContentResolver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.pm.ApplicationInfo;
8 | import android.content.pm.PackageInfo;
9 | import android.content.pm.PackageManager;
10 | import android.content.res.Resources;
11 | import android.net.Uri;
12 | import android.os.Build;
13 | import android.os.Bundle;
14 | import android.os.Parcel;
15 | import android.preference.CheckBoxPreference;
16 | import android.text.TextUtils;
17 | import android.view.Menu;
18 | import android.view.MenuItem;
19 | import android.widget.Toast;
20 |
21 | import java.io.File;
22 | import java.lang.reflect.Field;
23 | import java.lang.reflect.InvocationTargetException;
24 | import java.lang.reflect.Method;
25 | import java.util.Arrays;
26 | import java.util.HashSet;
27 | import java.util.LinkedList;
28 | import java.util.List;
29 | import java.util.Set;
30 |
31 | import de.robv.android.xposed.XC_MethodHook;
32 | import de.robv.android.xposed.XC_MethodReplacement;
33 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
34 |
35 | import static com.xposed.miuianesthetist.XposedHelpersWraper.findAndHookConstructor;
36 | import static com.xposed.miuianesthetist.XposedHelpersWraper.findAndHookMethod;
37 | import static com.xposed.miuianesthetist.XposedHelpersWraper.findClass;
38 | import static com.xposed.miuianesthetist.XposedHelpersWraper.findField;
39 | import static com.xposed.miuianesthetist.XposedHelpersWraper.findMethodBestMatch;
40 | import static com.xposed.miuianesthetist.XposedHelpersWraper.findMethodExact;
41 | import static com.xposed.miuianesthetist.XposedHelpersWraper.getObjectField;
42 | import static com.xposed.miuianesthetist.XposedHelpersWraper.getStaticBooleanField;
43 | import static com.xposed.miuianesthetist.XposedHelpersWraper.getStaticObjectField;
44 | import static com.xposed.miuianesthetist.XposedHelpersWraper.hookMethod;
45 | import static com.xposed.miuianesthetist.XposedHelpersWraper.invokeOriginalMethod;
46 | import static com.xposed.miuianesthetist.XposedHelpersWraper.log;
47 | import static com.xposed.miuianesthetist.XposedHelpersWraper.setBooleanField;
48 | import static com.xposed.miuianesthetist.XposedHelpersWraper.setIntField;
49 |
50 | public class DisableSecurityCheck extends BaseXposedHookLoadPackage {
51 | private static volatile Resources res;
52 | private static volatile MenuItem menu2;
53 |
54 | @Override
55 | public void initZygote(StartupParam startupParam) {
56 | }
57 |
58 | @Override
59 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
60 | if (lpparam.packageName.equals("android")) {
61 | try {
62 | handleAndroid(lpparam);
63 | } catch (Throwable t) {
64 | log(t);
65 | }
66 | }
67 | //SecurityCenter.apk
68 | if (lpparam.packageName.equals("com.miui.securitycenter")) {
69 | try {
70 | handleSecurityCenter(lpparam);
71 | } catch (Throwable t) {
72 | log(t);
73 | }
74 | }
75 | //Settings.apk
76 | if (lpparam.packageName.equals("com.android.settings")) {
77 | try {
78 | handleSettings(lpparam);
79 | } catch (Throwable t) {
80 | log(t);
81 | }
82 | }
83 |
84 | //MiuiInstaller.apk
85 | if (lpparam.packageName.equals("com.miui.packageinstaller")) {
86 | try {
87 | handleInstaller(lpparam);
88 | } catch (Throwable t) {
89 | log(t);
90 | }
91 | }
92 |
93 | }
94 |
95 | //Remove limit for installing system apps from unofficial channels
96 | private void handleInstaller(XC_LoadPackage.LoadPackageParam lpparam) {
97 | ClassLoader classLoader = lpparam.classLoader;
98 | Class> pia = findClass("com.android.packageinstaller.PackageInstallerActivity", classLoader);
99 | if (pia == null) return;
100 | List methods = new LinkedList<>();
101 | for (Method m : pia.getMethods()) {
102 | if (Arrays.equals(m.getParameterTypes(), new Class[]{Uri.class})) {
103 | methods.add(m);
104 | }
105 | }
106 | XC_MethodHook xc_methodHook = new XC_MethodHook() {
107 | @Override
108 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
109 | Field[] fields = pia.getDeclaredFields();
110 | Field P = null;
111 | for (Field f : fields) {
112 | if (f.getType() == List.class) {
113 | List sf = (List) getStaticObjectField(pia, f.getName());
114 | if (sf.contains("com.android.vending")) {
115 | P = f;
116 | break;
117 | }
118 | }
119 | }
120 | Uri uri = (Uri) param.args[0];
121 | String scheme = uri.getScheme();
122 | if (scheme == null || !scheme.equals("file")) return;
123 | String path = uri.getPath();
124 | if (TextUtils.isEmpty(path)) return;
125 | Class> ppc = findClass("com.android.packageinstaller.compat.PackageParserCompat", classLoader);
126 | Method parsePackage = findMethodBestMatch(ppc, "parsePackage", File.class, int.class);//file, 0
127 | Method createPackageUserState = findMethodBestMatch(ppc, "createPackageUserState");
128 | Method generatePackageInfo = findMethodBestMatch(ppc, "generatePackageInfo", Object.class, int[].class, int.class, long.class, long.class, Set.class, Object.class);
129 | //this.d = PackageParserCompat.generatePackageInfo(v1_1, v2, 0x1080, 0, 0, ((Set)v2), PackageParserCompat.createPackageUserState());
130 | File file = new File(path);
131 | Object v1_1 = parsePackage.invoke(null, file, 0);
132 | int[] v2 = {};
133 | PackageInfo packageInfo = (PackageInfo) generatePackageInfo.invoke(null, v1_1, v2, 0x1080, 0, 0, new HashSet(), createPackageUserState.invoke(null));
134 | String packageName = packageInfo.packageName;
135 | List p = (List) getStaticObjectField(pia, P.getName());
136 | if (p != null && !p.contains(packageName))
137 | p.add(packageName);
138 | }
139 | };
140 | for (Method m : methods) {
141 | String mname = m.getName();
142 | findAndHookMethod(pia, mname, Uri.class, xc_methodHook);
143 | }
144 |
145 | }
146 |
147 | private void handleSettings(XC_LoadPackage.LoadPackageParam lpparam) {
148 | ClassLoader classLoader = lpparam.classLoader;
149 | //Try to return a fake result of if an app is a system app, invalid
150 | Class> nshClass = findClass("com.android.settings.notification.NotificationSettingsHelper", classLoader);
151 | for (Method m : nshClass.getMethods()) {
152 | if (Arrays.equals(m.getParameterTypes(), new Class[]{int.class})) {
153 | log(m.getName());
154 | hookMethod(m, XC_MethodReplacement.returnConstant(false));
155 | break;
156 | }
157 | }
158 | final Class> appRowClass = findClass("com.android.settings.notification.MiuiNotificationBackend$AppRow", classLoader);
159 | findAndHookMethod("com.android.settings.notification.MiuiNotificationBackend", classLoader, "markAppRowWithBlockables",
160 | String[].class, appRowClass, String.class, new XC_MethodHook() {
161 | @Override
162 | protected void beforeHookedMethod(MethodHookParam param) {
163 | log("arg0:" + Arrays.toString((String[]) param.args[0]));
164 | log("arg2:" + param.args[2]);
165 | param.setResult(null);
166 | }
167 | });
168 |
169 | //Try to allow users disable AppNotificationSettings ,invalid
170 | Class> ans = findClass("com.android.settings.notification.AppNotificationSettings", classLoader);
171 | findAndHookMethod(ans, "onResume", new XC_MethodHook() {
172 | @Override
173 | protected void afterHookedMethod(MethodHookParam param) {
174 | Object o = null;
175 | try {
176 | o = findFirstFieldByExactType(ans, appRowClass).get(param.thisObject);
177 | } catch (IllegalAccessException e) {
178 | log(e);
179 | }
180 | setBooleanField(o, "systemApp", false);
181 | Method findPreference = findMethodBestMatch(ans, "findPreference", String.class);
182 | CheckBoxPreference block = null;
183 | try {
184 | if (findPreference != null) {
185 | findPreference.setAccessible(true);
186 | block = (CheckBoxPreference) findPreference.invoke(param.thisObject, "block");
187 | }
188 | } catch (Throwable t) {
189 | log(t);
190 | }
191 | if (block != null)
192 | block.setEnabled(true);
193 | }
194 | });
195 | }
196 |
197 | private void handleAndroid(XC_LoadPackage.LoadPackageParam lpparam) {
198 | ClassLoader classLoader = lpparam.classLoader;
199 | //Check if MIUI is global version
200 | if (null == iib) {
201 | iib = getStaticBooleanField(findClass("miui.os.Build", classLoader),
202 | "IS_INTERNATIONAL_BUILD");
203 | }
204 |
205 | //Disable integrity check when boot in services.jar
206 | Class sms = findClass("com.miui.server.SecurityManagerService"
207 | , classLoader);
208 | findAndHookConstructor(sms, Context.class, boolean.class/*onlyCore*/,
209 | new XC_MethodHook() {
210 | @Override
211 | protected void beforeHookedMethod(MethodHookParam param) {
212 | //Set the instance of SecurityManagerService class to be onlyCore mode,
213 | //then checkSystemSelfProtection() method will do nothing
214 | param.args[1] = true;
215 | }
216 | @Override
217 | protected void afterHookedMethod(MethodHookParam param) {
218 | //Set system apps' states to be not cracked
219 | setIntField(param.thisObject, "mSysAppCracked", 0);
220 | }
221 | });
222 |
223 | //Remove the limit for disabling system apps in services.jar
224 | findAndHookMethod("com.android.server.pm.PackageManagerServiceInjector"
225 | , classLoader, "isAllowedDisable",
226 | String.class, int.class, XC_MethodReplacement.returnConstant(true));
227 |
228 | //Remove the limit for installing WebViewGoogle manually on MIUI China ROM in services.jar
229 | findAndHookMethod("com.android.server.pm.PackageManagerServiceInjector",
230 | classLoader, "isAllowedInstall",
231 | Context.class, File.class, int.class, String.class,
232 | XC_MethodReplacement.returnConstant(true));
233 |
234 | //Prevent some ultra sticky system apps (MiuiDaemon, FindDevice, etc.) from running
235 | //after have been disabled in services.jar
236 | findAndHookMethod("com.android.server.am.ActivityManagerServiceInjector",
237 | classLoader, "shouldAddPersistApp", ApplicationInfo.class,
238 | new XC_MethodHook() {
239 | @Override
240 | protected void beforeHookedMethod(MethodHookParam param) {
241 | ApplicationInfo info = (ApplicationInfo) param.args[0];
242 | if (!info.packageName.equals("com.miui.greenguard") &&
243 | info.enabled) {
244 | param.setResult(true);
245 | return;
246 | }
247 | //Shorten TAG ActivityManagerServiceInjector
248 | log("AMSInjector", "persist app : " + info.packageName +
249 | " should not add to start");
250 | param.setResult(false);
251 | }
252 | });
253 |
254 | //Allow users disable system apps' notification chanel in framework.jar
255 | findAndHookConstructor("android.app.NotificationChannel", classLoader, Parcel.class, new XC_MethodHook() {
256 | @Override
257 | protected void afterHookedMethod(MethodHookParam param) {
258 | setBooleanField(param.thisObject, "mBlockableSystem", true);
259 | }
260 | });
261 | findAndHookConstructor("android.app.NotificationChannel", classLoader, String.class, CharSequence.class, int.class, new XC_MethodHook() {
262 | @Override
263 | protected void afterHookedMethod(MethodHookParam param) {
264 | setBooleanField(param.thisObject, "mBlockableSystem", true);
265 | }
266 | });
267 | //Return an intent before it get processed to avoid being hijacked in services.jar
268 | if (!iib) {
269 | Class> pmsClazz = findClass("com.android.server.pm.PackageManagerService",
270 | classLoader);
271 | findAndHookMethod("com.android.server.pm.PackageManagerServiceInjector"
272 | , classLoader, "checkMiuiIntent",
273 | pmsClazz, Intent.class, String.class, int.class, List.class, int.class,
274 | new XC_MethodReplacement() {
275 | @Override
276 | protected Object replaceHookedMethod(MethodHookParam param) {
277 | Intent intent = (Intent) param.args[1];
278 | if (("market".equals(intent.getScheme()) &&
279 | "android.intent.action.VIEW".equals(intent.getAction())) ||
280 | ("http".equals(intent.getScheme()) ||
281 | "https".equals(intent.getScheme())) &&
282 | "android.intent.action.VIEW".equals(intent.getAction())) {
283 | //Return mResolveInfo of the first arg pms
284 | return getObjectField(param.args[0], "mResolveInfo");
285 | }
286 | return invokeOriginalMethod(param.method, param.thisObject, param.args);
287 | }
288 | });
289 | }
290 | }
291 |
292 | private void handleSecurityCenter(XC_LoadPackage.LoadPackageParam lpparam) {
293 | ClassLoader classLoader = lpparam.classLoader;
294 | //Allow users to disable system apps using SecurityCenter's manage apps function
295 | //FIXME menuItem get disabled after selected and icon changed
296 | Class> ada = findClass("com.miui.appmanager.ApplicationsDetailsActivity",
297 | classLoader);
298 | XC_MethodHook xc_enable_menuItem = new XC_MethodHook() {
299 | @Override
300 | protected void afterHookedMethod(MethodHookParam param) {
301 | try {
302 | if (param.args.length == 1)
303 | //Index: 0 force stop; 1 uninstall/disable/enable; 2 clear data/cache
304 | menu2 = ((Menu) param.args[0]).getItem(1);
305 | if (menu2 != null)
306 | menu2.setEnabled(true);
307 | } catch (Throwable t) {
308 | log(t);
309 | }
310 | }
311 | };
312 | findAndHookMethod(ada, "onCreateOptionsMenu", Menu.class, xc_enable_menuItem);
313 | findAndHookMethod(ada, "onPrepareOptionsMenu", Menu.class, xc_enable_menuItem);
314 | findAndHookMethod(ada, "onResume", xc_enable_menuItem);
315 | //Allow users to revoke system app internet access permission
316 | //FIXME network control state preview abnormal, title disappear or turn off data, invalid after reboot
317 | findAndHookMethod(ada, "initData", new XC_MethodHook() {
318 | @Override
319 | protected void afterHookedMethod(MethodHookParam param) {
320 | try {
321 | initRes(param);
322 | int R_id_am_detail_net = res.getIdentifier("am_detail_net",
323 | "id", "com.miui.securitycenter");
324 | View am_detail_net = ((Activity) param.thisObject).findViewById(R_id_am_detail_net);
325 | am_detail_net.setVisibility(View.VISIBLE);
326 | } catch (Throwable t) {
327 | log(t);
328 | }
329 | }
330 | });
331 | findAndHookMethod(ada, "onClick", View.class, new XC_MethodHook() {
332 | @Override
333 | protected void beforeHookedMethod(MethodHookParam param) {
334 | try {
335 | setBooleanField(param.thisObject, "mIsSystem", false);
336 | } catch (Throwable t) {
337 | log(t);
338 | }
339 | }
340 | });
341 | //Allow users to set third-party launcher to be default
342 | findAndHookMethod("com.miui.securitycenter.provider.ThirdDesktopProvider",
343 | classLoader, "call", String.class, String.class,
344 | Bundle.class, new XC_MethodHook() {
345 | @Override
346 | protected void afterHookedMethod(MethodHookParam param) {
347 | try {
348 | if (param.args[0].equals("getModeAndList")) {
349 | Bundle result = (Bundle) param.getResult();
350 | //mode=0 can't use unauthorized third-party launcher;
351 | //mode=1 can't use official launcher; other value no limit
352 | result.putInt("mode", -1);
353 | param.setResult(result);
354 | }
355 | } catch (Throwable t) {
356 | log(t);
357 | }
358 | }
359 | });
360 |
361 | //Remove waiting time for applying device admin app
362 | findAndHookMethod("com.miui.permcenter.install.DeviceManagerApplyActivity", classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
363 | @Override
364 | protected void beforeHookedMethod(MethodHookParam param) {
365 | bypassSuperNotCalledException(param);
366 | }
367 | });
368 |
369 | //Remove waiting time for applying adb input
370 | findAndHookMethod("com.miui.permcenter.install.AdbInputApplyActivity", classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
371 | @Override
372 | protected void beforeHookedMethod(MethodHookParam param) {
373 | try {
374 | setProp(classLoader,"persist.security.adbinput","1");
375 | bypassSuperNotCalledException(param);
376 | } catch (Exception e) {
377 | log(e);
378 | }
379 | }
380 | });
381 |
382 | //Remove waiting time for applying install verify
383 | findAndHookMethod("com.miui.permcenter.install.AdbInstallVerifyActivity", classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
384 | @Override
385 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
386 | callPreference(param, "security_adb_install_enable", true);
387 | setProp(classLoader,"persist.security.adbinstall","1");
388 | bypassSuperNotCalledException(param);
389 | }
390 | });
391 |
392 | //Remove waiting time for applying root access
393 | findAndHookMethod("com.miui.permcenter.root.RootApplyActivity", classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
394 | @Override
395 | protected void beforeHookedMethod(MethodHookParam param) {
396 | try {
397 | grantRootAccess(param);
398 | } catch (Exception e) {
399 | log(e);
400 | }
401 | }
402 | });
403 | }
404 |
405 | private void grantRootAccess(XC_MethodHook.MethodHookParam param) {
406 | Activity activity = (Activity) param.thisObject;
407 | String mPkgName = activity.getIntent().getStringExtra("extra_pkgname");
408 | if (TextUtils.isEmpty(mPkgName)) {
409 | bypassSuperNotCalledException(param);
410 | return;
411 | }
412 | String mAppName = getAppName(param,mPkgName);
413 | Bundle bundle = new Bundle();
414 | bundle.putLong("extra_permission", 512);
415 | bundle.putInt("extra_action", 3);
416 | bundle.putStringArray("extra_package", new String[]{mPkgName});
417 | bundle.putInt("extra_flags", 0);
418 | Uri content_uri = Uri.parse("content://com.lbe.security.miui.permmgr");
419 | activity.getApplicationContext().getContentResolver().call(content_uri, "6", null, bundle);
420 | Resources resources = activity.getResources();
421 | int toast_root_apply_accept = resources.getIdentifier("toast_root_apply_accept", "string", "com.miui.securitycenter");
422 | Toast.makeText(activity, resources.getString(toast_root_apply_accept, mAppName), Toast.LENGTH_SHORT).show();
423 | bypassSuperNotCalledException(param);
424 | }
425 |
426 | private String getAppName(XC_MethodHook.MethodHookParam param,String packageName) {
427 | Activity activity = (Activity) param.thisObject;
428 | if ("root".equals(packageName)) {
429 | return "root";
430 | }
431 | if ("com.android.shell".equals(packageName)) {
432 | return "Interactive Shell";
433 | }
434 | try {
435 | PackageManager packageManager = activity.getApplicationContext().getPackageManager();
436 | return packageManager.getApplicationInfo(packageName,0).loadLabel(packageManager).toString();
437 | } catch (PackageManager.NameNotFoundException e) {
438 | return packageName;
439 | }
440 | }
441 |
442 | private void setProp(ClassLoader classLoader,String key,String value) throws IllegalAccessException, InvocationTargetException {
443 | Method setProp = findMethodExact("android.os.SystemProperties", classLoader, "set", String.class, String.class);
444 | setProp.invoke(null,key,value);
445 | }
446 |
447 | private void callPreference(XC_MethodHook.MethodHookParam param, String key, boolean value){
448 | Activity activity = (Activity) param.thisObject;
449 | ContentResolver contentResolver = activity.getContentResolver();
450 | Bundle bundle = new Bundle();
451 | bundle.putInt("type", 1);
452 | bundle.putString("key", key);
453 | bundle.putBoolean("value", value);
454 | remoteChange("SET", bundle,contentResolver);
455 | contentResolver.notifyChange(Uri.withAppendedPath(Uri.parse("content://com.miui.securitycenter.remoteprovider"), key), null, false);
456 | }
457 |
458 | private Bundle remoteChange(String action, Bundle bundle, ContentResolver contentResolver) {
459 | Uri uri;
460 | if (getMyUerId()==999) {
461 | Uri parse = Uri.parse("content://com.miui.securitycenter.remoteprovider");
462 | Uri.Builder buildUpon = parse.buildUpon();
463 | String authority = "0@" +
464 | parse.getEncodedAuthority();
465 | buildUpon.encodedAuthority(authority);
466 | uri = buildUpon.build();
467 | } else {
468 | uri = Uri.parse("content://com.miui.securitycenter.remoteprovider");
469 | }
470 | return contentResolver.call(uri, "callPreference", action, bundle);
471 | }
472 |
473 | private int getMyUerId() {
474 | int myUserId = 0;
475 | if (Build.VERSION.SDK_INT >= 21) {
476 | try {
477 | Integer num = (Integer) findMethodBestMatch(android.os.UserHandle.class, "myUserId").invoke(null);
478 | if (num != null) myUserId = num;
479 | } catch (Exception e) {
480 | log(e);
481 | }
482 | }
483 | return myUserId;
484 | }
485 |
486 | private void bypassSuperNotCalledException(XC_MethodHook.MethodHookParam param) {
487 | Activity activity = (Activity) param.thisObject;
488 | findField(Activity.class,"mCalled").setAccessible(true);
489 | setBooleanField(activity,"mCalled",true);
490 | activity.setResult(Activity.RESULT_OK);
491 | activity.finish();
492 | param.setResult(null);
493 | }
494 | }
495 |
--------------------------------------------------------------------------------
/app/src/main/java/com/xposed/miuianesthetist/XposedHelpersWraper.java:
--------------------------------------------------------------------------------
1 | package com.xposed.miuianesthetist;
2 |
3 | import android.content.res.Resources;
4 | import android.util.Log;
5 |
6 | import java.lang.reflect.Constructor;
7 | import java.lang.reflect.Field;
8 | import java.lang.reflect.Member;
9 | import java.lang.reflect.Method;
10 | import java.util.Set;
11 |
12 | import de.robv.android.xposed.XC_MethodHook;
13 | import de.robv.android.xposed.XposedBridge;
14 | import de.robv.android.xposed.XposedHelpers;
15 |
16 | public class XposedHelpersWraper {
17 | private static String TAG = "Xposed";
18 | public static String getTAG() {
19 | return TAG;
20 | }
21 |
22 | public static void setTAG(String TAG) {
23 | XposedHelpersWraper.TAG = TAG;
24 | }
25 |
26 | public static Set hookAllConstructors(Class> hookClass, XC_MethodHook callback) {
27 | try {
28 | return XposedBridge.hookAllConstructors(hookClass, callback);
29 | } catch (Throwable t) {
30 | log(t);
31 | }
32 | return null;
33 | }
34 |
35 | public static Set hookAllMethods(Class> hookClass, String methodName, XC_MethodHook callback) {
36 | try {
37 | return XposedBridge.hookAllMethods(hookClass, methodName, callback);
38 | } catch (Throwable t) {
39 | log(t);
40 | }
41 | return null;
42 | }
43 |
44 | public static XC_MethodHook.Unhook hookMethod(Member hookMethod, XC_MethodHook callback) {
45 | try {
46 | return XposedBridge.hookMethod(hookMethod, callback);
47 | } catch (Throwable t) {
48 | log(t);
49 | }
50 | return null;
51 | }
52 |
53 | public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args) {
54 | try {
55 | return XposedBridge.invokeOriginalMethod(method, thisObject, args);
56 | } catch (Throwable t) {
57 | log(t);
58 | }
59 | return null;
60 | }
61 |
62 | public synchronized static void log(String text) {
63 | Log.d(TAG, text);
64 | }
65 |
66 | public synchronized static void log(String TAG, String text) {
67 | Log.d(TAG, text);
68 | }
69 |
70 | public synchronized static void log(Throwable t) {
71 | Log.e(TAG, Log.getStackTraceString(t));
72 | }
73 |
74 | public synchronized static void log(String TAG, Throwable t) {
75 | Log.e(TAG, Log.getStackTraceString(t));
76 | }
77 |
78 | public static Class> findClass(String className, ClassLoader classLoader) {
79 | try {
80 | return XposedHelpers.findClass(className, classLoader);
81 | } catch (Throwable t) {
82 | log(t);
83 | }
84 | return null;
85 | }
86 |
87 | public static Field findField(Class> clazz, String fieldName) {
88 | try {
89 | return XposedHelpers.findField(clazz, fieldName);
90 | } catch (Throwable t) {
91 | log(t);
92 | }
93 | return null;
94 | }
95 |
96 | public static Field findFirstFieldByExactType(Class> clazz, Class> type) {
97 | try {
98 | return XposedHelpers.findFirstFieldByExactType(clazz, type);
99 | } catch (Throwable t) {
100 | log(t);
101 | }
102 | return null;
103 | }
104 |
105 | public static XC_MethodHook.Unhook findAndHookMethod(Class> clazz, String methodName, Object... parameterTypesAndCallback) {
106 | try {
107 | return XposedHelpers.findAndHookMethod(clazz, methodName, parameterTypesAndCallback);
108 | } catch (Throwable t) {
109 | log(t);
110 | }
111 | return null;
112 | }
113 |
114 | public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
115 | try {
116 | return XposedHelpers.findAndHookMethod(className, classLoader, methodName, parameterTypesAndCallback);
117 | } catch (Throwable t) {
118 | log(t);
119 | }
120 | return null;
121 | }
122 |
123 | public static Method findMethodExact(Class> clazz, String methodName, Object... parameterTypes) {
124 | try {
125 | return XposedHelpers.findMethodExact(clazz, methodName, parameterTypes);
126 | } catch (Throwable t) {
127 | log(t);
128 | }
129 | return null;
130 | }
131 |
132 | public static Method findMethodExact(String className, ClassLoader classLoader, String methodName, Object... parameterTypes) {
133 | try {
134 | return XposedHelpers.findMethodExact(className, classLoader, methodName, parameterTypes);
135 | } catch (Throwable t) {
136 | log(t);
137 | }
138 | return null;
139 | }
140 |
141 | public static Method findMethodExact(Class> clazz, String methodName, Class>... parameterTypes) {
142 | try {
143 | return XposedHelpers.findMethodExact(clazz, methodName, parameterTypes);
144 | } catch (Throwable t) {
145 | log(t);
146 | }
147 | return null;
148 | }
149 |
150 | public static Method[] findMethodsByExactParameters(Class> clazz, Class> returnType, Class>... parameterTypes) {
151 | try {
152 | return XposedHelpers.findMethodsByExactParameters(clazz, returnType, parameterTypes);
153 | } catch (Throwable t) {
154 | log(t);
155 | }
156 | return null;
157 | }
158 |
159 | public static Method findMethodBestMatch(Class> clazz, String methodName, Class>... parameterTypes) {
160 | try {
161 | return XposedHelpers.findMethodBestMatch(clazz, methodName, parameterTypes);
162 | } catch (Throwable t) {
163 | log(t);
164 | }
165 | return null;
166 | }
167 |
168 | public static Method findMethodBestMatch(Class> clazz, String methodName, Object... args) {
169 | try {
170 | return XposedHelpers.findMethodBestMatch(clazz, methodName, args);
171 | } catch (Throwable t) {
172 | log(t);
173 | }
174 | return null;
175 | }
176 |
177 | public static Method findMethodBestMatch(Class> clazz, String methodName, Class>[] parameterTypes, Object[] args) {
178 | try {
179 | return XposedHelpers.findMethodBestMatch(clazz, methodName, parameterTypes, args);
180 | } catch (Throwable t) {
181 | log(t);
182 | }
183 | return null;
184 | }
185 |
186 | public static Class>[] getParameterTypes(Object... args) {
187 | try {
188 | return XposedHelpers.getParameterTypes(args);
189 | } catch (Throwable t) {
190 | log(t);
191 | }
192 | return null;
193 | }
194 |
195 | public static Class>[] getClassesAsArray(Class>... clazzes) {
196 | try {
197 | return XposedHelpers.getClassesAsArray(clazzes);
198 | } catch (Throwable t) {
199 | log(t);
200 | }
201 | return null;
202 | }
203 |
204 | public static Constructor> findConstructorExact(Class> clazz, Object... parameterTypes) {
205 | try {
206 | return XposedHelpers.findConstructorExact(clazz, parameterTypes);
207 | } catch (Throwable t) {
208 | log(t);
209 | }
210 | return null;
211 | }
212 |
213 | public static Constructor> findConstructorExact(String className, ClassLoader classLoader, Object... parameterTypes) {
214 | try {
215 | return XposedHelpers.findConstructorExact(className, classLoader, parameterTypes);
216 | } catch (Throwable t) {
217 | log(t);
218 | }
219 | return null;
220 | }
221 |
222 | public static Constructor> findConstructorExact(Class> clazz, Class>... parameterTypes) {
223 | try {
224 | return XposedHelpers.findConstructorExact(clazz, parameterTypes);
225 | } catch (Throwable t) {
226 | log(t);
227 | }
228 | return null;
229 | }
230 |
231 | public static XC_MethodHook.Unhook findAndHookConstructor(Class> clazz, Object... parameterTypesAndCallback) {
232 | try {
233 | return XposedHelpers.findAndHookConstructor(clazz, parameterTypesAndCallback);
234 | } catch (Throwable t) {
235 | log(t);
236 | }
237 | return null;
238 | }
239 |
240 | public static XC_MethodHook.Unhook findAndHookConstructor(String className, ClassLoader classLoader, Object... parameterTypesAndCallback) {
241 | try {
242 | return XposedHelpers.findAndHookConstructor(className, classLoader, parameterTypesAndCallback);
243 | } catch (Throwable t) {
244 | log(t);
245 | }
246 | return null;
247 | }
248 |
249 | public static Constructor> findConstructorBestMatch(Class> clazz, Class>... parameterTypes) {
250 | try {
251 | return XposedHelpers.findConstructorBestMatch(clazz, parameterTypes);
252 | } catch (Throwable t) {
253 | log(t);
254 | }
255 | return null;
256 | }
257 |
258 | public static Constructor> findConstructorBestMatch(Class> clazz, Object... args) {
259 | try {
260 | return XposedHelpers.findConstructorBestMatch(clazz, args);
261 | } catch (Throwable t) {
262 | log(t);
263 | }
264 | return null;
265 | }
266 |
267 | public static Constructor> findConstructorBestMatch(Class> clazz, Class>[] parameterTypes, Object[] args) {
268 | try {
269 | return XposedHelpers.findConstructorBestMatch(clazz, parameterTypes, args);
270 | } catch (Throwable t) {
271 | log(t);
272 | }
273 | return null;
274 | }
275 |
276 | public static void setObjectField(Object obj, String fieldName, Object value) {
277 | try {
278 | XposedHelpers.setObjectField(obj, fieldName, value);
279 | } catch (Throwable t) {
280 | log(t);
281 | }
282 | }
283 |
284 | public static void setBooleanField(Object obj, String fieldName, boolean value) {
285 | try {
286 | XposedHelpers.setBooleanField(obj, fieldName, value);
287 | } catch (Throwable t) {
288 | log(t);
289 | }
290 | }
291 |
292 | public static void setByteField(Object obj, String fieldName, byte value) {
293 | try {
294 | XposedHelpers.setByteField(obj, fieldName, value);
295 | } catch (Throwable t) {
296 | log(t);
297 | }
298 | }
299 |
300 | public static void setCharField(Object obj, String fieldName, char value) {
301 | try {
302 | XposedHelpers.setCharField(obj, fieldName, value);
303 | } catch (Throwable t) {
304 | log(t);
305 | }
306 | }
307 |
308 | public static void setDoubleField(Object obj, String fieldName, double value) {
309 | try {
310 | XposedHelpers.setDoubleField(obj, fieldName, value);
311 | } catch (Throwable t) {
312 | log(t);
313 | }
314 | }
315 |
316 | public static void setFloatField(Object obj, String fieldName, float value) {
317 | try {
318 | XposedHelpers.setFloatField(obj, fieldName, value);
319 | } catch (Throwable t) {
320 | log(t);
321 | }
322 | }
323 |
324 | public static void setIntField(Object obj, String fieldName, int value) {
325 | try {
326 | XposedHelpers.setIntField(obj, fieldName, value);
327 | } catch (Throwable t) {
328 | log(t);
329 | }
330 | }
331 |
332 | public static void setLongField(Object obj, String fieldName, long value) {
333 | try {
334 | XposedHelpers.setLongField(obj, fieldName, value);
335 | } catch (Throwable t) {
336 | log(t);
337 | }
338 | }
339 |
340 | public static void setShortField(Object obj, String fieldName, short value) {
341 | try {
342 | XposedHelpers.setShortField(obj, fieldName, value);
343 | } catch (Throwable t) {
344 | log(t);
345 | }
346 | }
347 |
348 | public static Object getObjectField(Object obj, String fieldName) {
349 | try {
350 | return XposedHelpers.getObjectField(obj, fieldName);
351 | } catch (Throwable t) {
352 | log(t);
353 | }
354 | return null;
355 | }
356 |
357 | public static Object getSurroundingThis(Object obj) {
358 | try {
359 | return XposedHelpers.getSurroundingThis(obj);
360 | } catch (Throwable t) {
361 | log(t);
362 | }
363 | return null;
364 | }
365 |
366 | public static boolean getBooleanField(Object obj, String fieldName) {
367 | try {
368 | return XposedHelpers.getBooleanField(obj, fieldName);
369 | } catch (Throwable t) {
370 | log(t);
371 | }
372 | return false;
373 | }
374 |
375 | public static byte getByteField(Object obj, String fieldName) {
376 | try {
377 | return XposedHelpers.getByteField(obj, fieldName);
378 | } catch (Throwable t) {
379 | log(t);
380 | }
381 | return 0;
382 | }
383 |
384 | public static char getCharField(Object obj, String fieldName) {
385 | try {
386 | return XposedHelpers.getCharField(obj, fieldName);
387 | } catch (Throwable t) {
388 | log(t);
389 | }
390 | return 0;
391 | }
392 |
393 | public static double getDoubleField(Object obj, String fieldName) {
394 | try {
395 | return XposedHelpers.getDoubleField(obj, fieldName);
396 | } catch (Throwable t) {
397 | log(t);
398 | }
399 | return 0;
400 | }
401 |
402 | public static float getFloatField(Object obj, String fieldName) {
403 | try {
404 | return XposedHelpers.getFloatField(obj, fieldName);
405 | } catch (Throwable t) {
406 | log(t);
407 | }
408 | return 0;
409 | }
410 |
411 | public static int getIntField(Object obj, String fieldName) {
412 | try {
413 | return XposedHelpers.getIntField(obj, fieldName);
414 | } catch (Throwable t) {
415 | log(t);
416 | }
417 | return 0;
418 | }
419 |
420 | public static long getLongField(Object obj, String fieldName) {
421 | try {
422 | return XposedHelpers.getLongField(obj, fieldName);
423 | } catch (Throwable t) {
424 | log(t);
425 | }
426 | return 0;
427 | }
428 |
429 | public static short getShortField(Object obj, String fieldName) {
430 | try {
431 | return XposedHelpers.getShortField(obj, fieldName);
432 | } catch (Throwable t) {
433 | log(t);
434 | }
435 | return 0;
436 | }
437 |
438 | public static void setStaticObjectField(Class> clazz, String fieldName, Object value) {
439 | try {
440 | XposedHelpers.setStaticObjectField(clazz, fieldName, value);
441 | } catch (Throwable t) {
442 | log(t);
443 | }
444 | }
445 |
446 | public static void setStaticBooleanField(Class> clazz, String fieldName, boolean value) {
447 | try {
448 | XposedHelpers.setStaticBooleanField(clazz, fieldName, value);
449 | } catch (Throwable t) {
450 | log(t);
451 | }
452 | }
453 |
454 | public static void setStaticByteField(Class> clazz, String fieldName, byte value) {
455 | try {
456 | XposedHelpers.setStaticByteField(clazz, fieldName, value);
457 | } catch (Throwable t) {
458 | log(t);
459 | }
460 | }
461 |
462 | public static void setStaticCharField(Class> clazz, String fieldName, char value) {
463 | try {
464 | XposedHelpers.setStaticCharField(clazz, fieldName, value);
465 | } catch (Throwable t) {
466 | log(t);
467 | }
468 | }
469 |
470 | public static void setStaticDoubleField(Class> clazz, String fieldName, double value) {
471 | try {
472 | XposedHelpers.setStaticDoubleField(clazz, fieldName, value);
473 | } catch (Throwable t) {
474 | log(t);
475 | }
476 | }
477 |
478 | public static void setStaticFloatField(Class> clazz, String fieldName, float value) {
479 | try {
480 | XposedHelpers.setStaticFloatField(clazz, fieldName, value);
481 | } catch (Throwable t) {
482 | log(t);
483 | }
484 | }
485 |
486 | public static void setStaticIntField(Class> clazz, String fieldName, int value) {
487 | try {
488 | XposedHelpers.setStaticIntField(clazz, fieldName, value);
489 | } catch (Throwable t) {
490 | log(t);
491 | }
492 | }
493 |
494 | public static void setStaticLongField(Class> clazz, String fieldName, long value) {
495 | try {
496 | XposedHelpers.setStaticLongField(clazz, fieldName, value);
497 | } catch (Throwable t) {
498 | log(t);
499 | }
500 | }
501 |
502 | public static void setStaticShortField(Class> clazz, String fieldName, short value) {
503 | try {
504 | XposedHelpers.setStaticShortField(clazz, fieldName, value);
505 | } catch (Throwable t) {
506 | log(t);
507 | }
508 | }
509 |
510 | public static Object getStaticObjectField(Class> clazz, String fieldName) {
511 | try {
512 | return XposedHelpers.getStaticObjectField(clazz, fieldName);
513 | } catch (Throwable t) {
514 | log(t);
515 | }
516 | return null;
517 | }
518 |
519 | public static boolean getStaticBooleanField(Class> clazz, String fieldName) {
520 | try {
521 | return XposedHelpers.getStaticBooleanField(clazz, fieldName);
522 | } catch (Throwable t) {
523 | log(t);
524 | }
525 | return false;
526 | }
527 |
528 | public static byte getStaticByteField(Class> clazz, String fieldName) {
529 | try {
530 | return XposedHelpers.getStaticByteField(clazz, fieldName);
531 | } catch (Throwable t) {
532 | log(t);
533 | }
534 | return 0;
535 | }
536 |
537 | public static char getStaticCharField(Class> clazz, String fieldName) {
538 | try {
539 | return XposedHelpers.getStaticCharField(clazz, fieldName);
540 | } catch (Throwable t) {
541 | log(t);
542 | }
543 | return 0;
544 | }
545 |
546 | public static double getStaticDoubleField(Class> clazz, String fieldName) {
547 | try {
548 | return XposedHelpers.getStaticDoubleField(clazz, fieldName);
549 | } catch (Throwable t) {
550 | log(t);
551 | }
552 | return 0;
553 | }
554 |
555 | public static float getStaticFloatField(Class> clazz, String fieldName) {
556 | try {
557 | return XposedHelpers.getStaticFloatField(clazz, fieldName);
558 | } catch (Throwable t) {
559 | log(t);
560 | }
561 | return 0;
562 | }
563 |
564 | public static int getStaticIntField(Class> clazz, String fieldName) {
565 | try {
566 | return XposedHelpers.getStaticIntField(clazz, fieldName);
567 | } catch (Throwable t) {
568 | log(t);
569 | }
570 | return 0;
571 | }
572 |
573 | public static long getStaticLongField(Class> clazz, String fieldName) {
574 | try {
575 | return XposedHelpers.getStaticLongField(clazz, fieldName);
576 | } catch (Throwable t) {
577 | log(t);
578 | }
579 | return 0;
580 | }
581 |
582 | public static short getStaticShortField(Class> clazz, String fieldName) {
583 | try {
584 | return XposedHelpers.getStaticShortField(clazz, fieldName);
585 | } catch (Throwable t) {
586 | log(t);
587 | }
588 | return 0;
589 | }
590 |
591 | public static Object callMethod(Object obj, String methodName, Object... args) {
592 | try {
593 | return XposedHelpers.callMethod(obj, methodName, args);
594 | } catch (Throwable t) {
595 | log(t);
596 | }
597 | return null;
598 | }
599 |
600 | public static Object callMethod(Object obj, String methodName, Class>[] parameterTypes, Object... args) {
601 | try {
602 | return XposedHelpers.callMethod(obj, methodName, parameterTypes, args);
603 | } catch (Throwable t) {
604 | log(t);
605 | }
606 | return null;
607 | }
608 |
609 | public static Object callStaticMethod(Class> clazz, String methodName, Object... args) {
610 | try {
611 | return XposedHelpers.callMethod(clazz, methodName, args);
612 | } catch (Throwable t) {
613 | log(t);
614 | }
615 | return null;
616 | }
617 |
618 | public static Object callStaticMethod(Class> clazz, String methodName, Class>[] parameterTypes, Object... args) {
619 | try {
620 | return XposedHelpers.callStaticMethod(clazz, methodName, parameterTypes, args);
621 | } catch (Throwable t) {
622 | log(t);
623 | }
624 | return null;
625 | }
626 |
627 | public static Object newInstance(Class> clazz, Object... args) {
628 | try {
629 | return XposedHelpers.newInstance(clazz, args);
630 | } catch (Throwable t) {
631 | log(t);
632 | }
633 | return null;
634 | }
635 |
636 | public static Object newInstance(Class> clazz, Class>[] parameterTypes, Object... args) {
637 | try {
638 | return XposedHelpers.newInstance(clazz, parameterTypes, args);
639 | } catch (Throwable t) {
640 | log(t);
641 | }
642 | return null;
643 | }
644 |
645 | public static Object setAdditionalInstanceField(Object obj, String key, Object value) {
646 | try {
647 | return XposedHelpers.setAdditionalInstanceField(obj, key, value);
648 | } catch (Throwable t) {
649 | log(t);
650 | }
651 | return null;
652 | }
653 |
654 | public static Object getAdditionalInstanceField(Object obj, String key) {
655 | try {
656 | return XposedHelpers.getAdditionalInstanceField(obj, key);
657 | } catch (Throwable t) {
658 | log(t);
659 | }
660 | return null;
661 | }
662 |
663 | public static Object removeAdditionalInstanceField(Object obj, String key) {
664 | try {
665 | return XposedHelpers.removeAdditionalInstanceField(obj, key);
666 | } catch (Throwable t) {
667 | log(t);
668 | }
669 | return null;
670 | }
671 |
672 | public static Object setAdditionalStaticField(Object obj, String key, Object value) {
673 | try {
674 | return XposedHelpers.setAdditionalStaticField(obj, key, value);
675 | } catch (Throwable t) {
676 | log(t);
677 | }
678 | return null;
679 | }
680 |
681 | public static Object getAdditionalStaticField(Object obj, String key) {
682 | try {
683 | return XposedHelpers.getAdditionalStaticField(obj, key);
684 | } catch (Throwable t) {
685 | log(t);
686 | }
687 | return null;
688 | }
689 |
690 | public static Object removeAdditionalStaticField(Object obj, String key) {
691 | try {
692 | return XposedHelpers.removeAdditionalStaticField(obj, key);
693 | } catch (Throwable t) {
694 | log(t);
695 | }
696 | return null;
697 | }
698 |
699 | public static Object setAdditionalStaticField(Class> clazz, String key, Object value) {
700 | try {
701 | return XposedHelpers.setAdditionalStaticField(clazz, key, value);
702 | } catch (Throwable t) {
703 | log(t);
704 | }
705 | return null;
706 | }
707 |
708 | public static Object getAdditionalStaticField(Class> clazz, String key) {
709 | try {
710 | return XposedHelpers.getAdditionalStaticField(clazz, key);
711 | } catch (Throwable t) {
712 | log(t);
713 | }
714 | return null;
715 | }
716 |
717 | public static Object removeAdditionalStaticField(Class> clazz, String key) {
718 | try {
719 | return XposedHelpers.removeAdditionalStaticField(clazz, key);
720 | } catch (Throwable t) {
721 | log(t);
722 | }
723 | return null;
724 | }
725 |
726 | public static byte[] assetAsByteArray(Resources res, String path) {
727 | try {
728 | return XposedHelpers.assetAsByteArray(res, path);
729 | } catch (Throwable t) {
730 | log(t);
731 | }
732 | return null;
733 | }
734 |
735 | public static String getMD5Sum(String file) {
736 | try {
737 | return XposedHelpers.getMD5Sum(file);
738 | } catch (Throwable t) {
739 | log(t);
740 | }
741 | return null;
742 | }
743 |
744 | }
745 |
--------------------------------------------------------------------------------
/app/src/main/res/values-en/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MIUI Anesthetist
4 | Carry out surgical strikes against MIUI
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MIUI麻醉师
4 | 对MIUI进行外科手术式打击
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MIUI麻醉師
4 | 對MIUI進行外科手術式打擊
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MIUI Anesthetist
3 | Carry out surgical strikes against MIUI
4 |
5 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 |
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.6.0-alpha07'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 |
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neoblackxt/MIUIAnesthetist/3707cb1a4d023c5b34807e39fcdaa5918652cd54/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jul 12 10:33:01 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------