├── .gitattributes
├── .github
├── dependabot.yml
└── workflows
│ └── android.yml
├── .gitignore
├── .idea
└── icon.png
├── LICENSE
├── MiuiHomeR.png
├── README.md
├── app
├── .gitignore
├── build.gradle.kts
├── dict.txt
├── libs
│ ├── animation-release.aar
│ ├── annotation-release.aar
│ ├── appcompat-release.aar
│ ├── appcompat-resources-release.aar
│ ├── blur-release.aar
│ ├── core-release.aar
│ ├── haptic-release.aar
│ ├── internal-release.aar
│ ├── os-release.aar
│ ├── preference-release.aar
│ ├── recyclerview-release.aar
│ ├── smooth-release.aar
│ └── springback-release.aar
├── proguard-log.pro
├── proguard-rules.pro
└── src
│ ├── .gitignore
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── xposed_init
│ ├── java
│ └── com
│ │ ├── yuk
│ │ └── miuiHomeR
│ │ │ ├── Application.kt
│ │ │ ├── MainHook.kt
│ │ │ ├── hook
│ │ │ ├── AllAppsContainerViewBlur.kt
│ │ │ ├── AllowMoveAllWidgetToMinus.kt
│ │ │ ├── AlwaysBlurWallpaper.kt
│ │ │ ├── AlwaysShowMiuiWidget.kt
│ │ │ ├── AlwaysShowStatusClock.kt
│ │ │ ├── AnimDurationRatio.kt
│ │ │ ├── AppDrawer.kt
│ │ │ ├── BaseHook.kt
│ │ │ ├── BigIconCorner.kt
│ │ │ ├── BlurLevel.kt
│ │ │ ├── BlurRadius.kt
│ │ │ ├── CloseFolderWhenLaunchedApp.kt
│ │ │ ├── DisableRecentViewWallpaperDarken.kt
│ │ │ ├── Dock.kt
│ │ │ ├── DoubleTapController.kt
│ │ │ ├── DoubleTapToSleep.kt
│ │ │ ├── EnableBigFolderIconBlur.kt
│ │ │ ├── EnableBlurWhenOpenFolder.kt
│ │ │ ├── EnableFolderIconBlur.kt
│ │ │ ├── FoldDeviceDock.kt
│ │ │ ├── FolderAnim.kt
│ │ │ ├── FolderColumnsCount.kt
│ │ │ ├── FolderVerticalPadding.kt
│ │ │ ├── HapticFeedback.kt
│ │ │ ├── HideSeekPoint.kt
│ │ │ ├── HideStatusBarWhenEnterRecent.kt
│ │ │ ├── HideWidgetTitles.kt
│ │ │ ├── HomeSettings.kt
│ │ │ ├── IconTitleColor.kt
│ │ │ ├── IconTitleScrolling.kt
│ │ │ ├── IconTitleSize.kt
│ │ │ ├── InfiniteScroll.kt
│ │ │ ├── OverlapMode.kt
│ │ │ ├── Recent.kt
│ │ │ ├── RemoveCardAnim.kt
│ │ │ ├── ResourcesHook.kt
│ │ │ ├── SetDeviceLevel.kt
│ │ │ ├── ShortcutBlur.kt
│ │ │ ├── ShortcutItemCount.kt
│ │ │ ├── ShortcutSmallWindow.kt
│ │ │ ├── ShowDockIconTitle.kt
│ │ │ ├── TaskViewHorizontal.kt
│ │ │ ├── TaskViewVertical.kt
│ │ │ ├── UnlockAnim.kt
│ │ │ └── UnlockHotseatIcon.kt
│ │ │ ├── provider
│ │ │ └── SharedPrefsProvider.kt
│ │ │ ├── ui
│ │ │ ├── AboutActivity.kt
│ │ │ ├── AppDrawerActivity.kt
│ │ │ ├── DockActivity.kt
│ │ │ ├── FolderActivity.kt
│ │ │ ├── HomeActivity.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── OtherActivity.kt
│ │ │ ├── RecentActivity.kt
│ │ │ ├── SettingsActivity.kt
│ │ │ ├── WidgetActivity.kt
│ │ │ └── base
│ │ │ │ ├── BaseAppCompatActivity.kt
│ │ │ │ ├── BasePreferenceFragment.kt
│ │ │ │ └── SubFragment.kt
│ │ │ ├── utils
│ │ │ ├── AppManager.java
│ │ │ ├── BackupUtils.kt
│ │ │ ├── Helpers.kt
│ │ │ ├── PrefsMap.java
│ │ │ ├── PrefsUtils.kt
│ │ │ ├── ResourcesHookData.kt
│ │ │ ├── ResourcesHookMap.kt
│ │ │ └── ktx
│ │ │ │ ├── AppUtil.kt
│ │ │ │ └── KotlinXposedHelper.kt
│ │ │ └── view
│ │ │ └── CircleImageView.java
│ │ └── zhenxiang
│ │ └── blur
│ │ ├── BackgroundBlurDrawableExtensions.kt
│ │ ├── BlurFrameLayout.kt
│ │ ├── BlurLinearLayout.kt
│ │ ├── SystemBlurController.kt
│ │ ├── ViewExtensions.kt
│ │ └── model
│ │ └── CornerRadius.kt
│ └── res
│ ├── drawable-440dpi
│ ├── ic_moralnorm.webp
│ └── ic_yukonga.webp
│ ├── drawable
│ ├── ic_launcher_background.xml
│ ├── ic_launcher_foreground.xml
│ ├── ic_settings.xml
│ ├── ic_task_small_window_dark.xml
│ └── ic_task_small_window_light.xml
│ ├── layout
│ ├── activity_about.xml
│ ├── activity_main.xml
│ └── preference_round_layout.xml
│ ├── mipmap-anydpi-v26
│ └── ic_launcher.xml
│ ├── values-af
│ └── strings.xml
│ ├── values-ar
│ └── strings.xml
│ ├── values-ca
│ └── strings.xml
│ ├── values-cs
│ └── strings.xml
│ ├── values-da
│ └── strings.xml
│ ├── values-de
│ └── strings.xml
│ ├── values-el
│ └── strings.xml
│ ├── values-es
│ └── strings.xml
│ ├── values-fa
│ └── strings.xml
│ ├── values-fi
│ └── strings.xml
│ ├── values-fr
│ └── strings.xml
│ ├── values-he
│ └── strings.xml
│ ├── values-hu
│ └── strings.xml
│ ├── values-id
│ └── strings.xml
│ ├── values-it
│ └── strings.xml
│ ├── values-ja
│ └── strings.xml
│ ├── values-ka
│ └── strings.xml
│ ├── values-ko
│ └── strings.xml
│ ├── values-night
│ └── colors.xml
│ ├── values-nl
│ └── strings.xml
│ ├── values-no
│ └── strings.xml
│ ├── values-pl
│ └── strings.xml
│ ├── values-pt-rBR
│ └── strings.xml
│ ├── values-pt
│ └── strings.xml
│ ├── values-ro
│ └── strings.xml
│ ├── values-ru-rRU
│ └── strings.xml
│ ├── values-ru
│ └── strings.xml
│ ├── values-sr
│ └── strings.xml
│ ├── values-sv
│ └── strings.xml
│ ├── values-th
│ └── strings.xml
│ ├── values-tr
│ └── strings.xml
│ ├── values-uk
│ └── strings.xml
│ ├── values-uz
│ └── strings.xml
│ ├── values-vi
│ └── strings.xml
│ ├── values-zh-rCN
│ └── strings.xml
│ ├── values-zh-rHK
│ └── strings.xml
│ ├── values-zh-rTW
│ └── strings.xml
│ ├── values
│ ├── arrays.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── strings.xml
│ └── themes.xml
│ └── xml
│ ├── prefs_about.xml
│ ├── prefs_app_drawer.xml
│ ├── prefs_dock.xml
│ ├── prefs_folder.xml
│ ├── prefs_home.xml
│ ├── prefs_main.xml
│ ├── prefs_other.xml
│ ├── prefs_recent.xml
│ ├── prefs_settings.xml
│ └── prefs_widget.xml
├── build.gradle.kts
├── crowdin.yml
├── dependabot.yml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── hidden-api
├── .gitignore
├── build.gradle.kts
├── proguard-rules.pro
└── src
│ └── main
│ └── java
│ ├── android
│ └── view
│ │ └── ViewRootImpl.java
│ └── com
│ └── android
│ └── internal
│ └── graphics
│ └── drawable
│ └── BackgroundBlurDrawable.java
└── settings.gradle.kts
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "gradle"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
--------------------------------------------------------------------------------
/.github/workflows/android.yml:
--------------------------------------------------------------------------------
1 | name: Android CI
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths-ignore:
7 | - 'README.md'
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v3.2.0
15 |
16 | - name: Setup JDK 17
17 | uses: actions/setup-java@v3.9.0
18 | with:
19 | java-version: '17'
20 | distribution: 'adopt'
21 |
22 | - name: Cache Gradle Dependencies
23 | uses: actions/cache@v3.2.2
24 | with:
25 | path: |
26 | ~/.gradle/caches
27 | ~/.gradle/wrapper
28 | !~/.gradle/caches/build-cache-*
29 | key: gradle-deps-core-${{ hashFiles('**/build.gradle.kts') }}
30 | restore-keys: gradle-deps
31 |
32 | - name: Cache Gradle Build
33 | uses: actions/cache@v3.2.2
34 | with:
35 | path: |
36 | ~/.gradle/caches/build-cache-*
37 | ~/.gradle/buildOutputCleanup/cache.properties
38 | key: gradle-builds-core-${{ github.sha }}
39 | restore-keys: gradle-builds
40 |
41 | - name: Build with Gradle
42 | run: |
43 | echo ${{ secrets.SIGNING_KEY }} | base64 -d > keystore.jks
44 | bash ./gradlew assemble
45 | env:
46 | KEYSTORE_PATH: "../keystore.jks"
47 | KEYSTORE_PASS: ${{ secrets.KEY_STORE_PASSWORD }}
48 | KEY_ALIAS: ${{ secrets.ALIAS }}
49 | KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
50 |
51 | - name: Upload Release APK
52 | uses: actions/upload-artifact@v3
53 | with:
54 | name: MiuiHomeR_Release
55 | path: "app/build/outputs/apk/release/*.apk"
56 |
57 | - name: Upload Debug APK
58 | uses: actions/upload-artifact@v3
59 | with:
60 | name: MiuiHomeR_Debug
61 | path: "app/build/outputs/apk/debug/*.apk"
62 |
63 | - name: Find apk
64 | run: |
65 | echo "RELEASE=$(find 'app/build/outputs/apk/release' -name '*.apk')" >> $GITHUB_ENV
66 | echo "DEBUG=$(find 'app/build/outputs/apk/debug' -name '*.apk')" >> $GITHUB_ENV
67 |
68 | - name: Post to channel
69 | if: contains(github.event.head_commit.message, '[skip post]') == false
70 | env:
71 | CHANNEL_ID: ${{ secrets.CHANNEL_ID }}
72 | BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
73 | RELEASE: ${{ env.RELEASE }}
74 | DEBUG: ${{ env.DEBUG }}
75 | COMMIT_MESSAGE: |+
76 | New push in Github\!
77 | ```
78 | ${{ github.event.head_commit.message }}
79 | ```
80 | run: |
81 | ESCAPED=`python3 -c 'import json,os,urllib.parse; print(urllib.parse.quote(json.dumps(os.environ["COMMIT_MESSAGE"])))'`
82 | curl -v "https://api.telegram.org/bot${BOT_TOKEN}/sendMediaGroup?chat_id=${CHANNEL_ID}&media=%5B%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Frelease%22%7D%2C%7B%22type%22%3A%22document%22%2C%20%22media%22%3A%22attach%3A%2F%2Fdebug%22%2C%22parse_mode%22%3A%22MarkdownV2%22%2C%22caption%22%3A${ESCAPED}%7D%5D" -F release="@$RELEASE" -F debug="@$DEBUG"
83 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 | *.aab
5 |
6 | # Files for the ART/Dalvik VM
7 | *.dex
8 |
9 | # Java class files
10 | *.class
11 |
12 | # Generated files
13 | bin/
14 | gen/
15 | out/
16 |
17 | # Gradle files
18 | .gradle/
19 | build/
20 |
21 | # Local configuration file (sdk path, etc)
22 | local.properties
23 |
24 | # Proguard folder generated by Eclipse
25 | proguard/
26 |
27 | # Log Files
28 | *.log
29 |
30 | # Android Studio Navigation editor temp files
31 | .navigation/
32 |
33 | # Android Studio captures folder
34 | captures/
35 |
36 | # IntelliJ
37 | *.iml
38 | .idea/
39 |
40 | # Keystore files
41 | # Uncomment the following lines if you do not want to check your keystore files in.
42 | #*.jks
43 | #*.keystore
44 |
45 | # External native build folder generated in Android Studio 2.2 and later
46 | .externalNativeBuild
47 |
48 | # Google Services (e.g. APIs or Firebase)
49 | google-services.json
50 |
51 | # Freeline
52 | freeline.py
53 | freeline/
54 | freeline_project_description.json
55 |
56 | # fastlane
57 | fastlane/report.xml
58 | fastlane/Preview.html
59 | fastlane/screenshots
60 | fastlane/test_output
61 | fastlane/readme.md
--------------------------------------------------------------------------------
/.idea/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/.idea/icon.png
--------------------------------------------------------------------------------
/MiuiHomeR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/MiuiHomeR.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
MiuiHomeR
4 |
5 | Make MiuiHome Great Again - Xposed
6 |
7 | [](https://github.com/qqlittleice/MiuiHome_R/actions/workflows/android.yml)
8 | [](https://crowdin.com/project/miuihomer)
9 | [](https://t.me/MiuiHome_Xposed)
10 | [](https://github.com/Xposed-Modules-Repo/com.yuk.miuihomeR/releases/latest)
11 |
12 | 
13 |
14 |
15 |
16 | -----
17 |
18 | ## Translation
19 |
20 | [Crowdin](https://crowdin.com/project/miuihomer/invite?h=1b68e3fdf40ff94a42d8409affcb24f71535875)
21 |
22 | ## Creates
23 |
24 |
25 |
26 | - [AndroidHiddenApiBypass](https://github.com/LSPosed/AndroidHiddenApiBypass)
27 | -- [Apache License 2.0](https://github.com/LSPosed/AndroidHiddenApiBypass/blob/main/LICENSE)
28 | - [EzXHelper](https://github.com/KyuubiRan/EzXHelper)
29 | -- [Apache License 2.0](https://github.com/KyuubiRan/EzXHelper/blob/master/LICENSE)
30 | - [XposedBridge](https://github.com/rovo89/XposedBridge)
31 | -- [Apache License 2.0](https://github.com/rovo89/XposedBridge/blob/art/NOTICE.txt)
32 |
33 | - [AndroidSystemBlur](https://github.com/Lucchetto/AndroidSystemBlur)
34 | -- [GNU General Public License v2.0](https://github.com/Lucchetto/AndroidSystemBlur/blob/master/LICENSE.txt)
35 |
36 | - [BiliRoaming](https://github.com/yujincheng08/BiliRoaming)
37 | -- [GNU General Public License v3.0](https://github.com/yujincheng08/BiliRoaming/blob/master/LICENSE)
38 | - [CustoMIUIzer](https://code.highspec.ru/Mikanoshi/CustoMIUIzer)
39 | -- [GNU General Public License v3.0](https://code.highspec.ru/Mikanoshi/CustoMIUIzer/src/branch/master/LICENSE)
40 | - [LSPosed](https://github.com/LSPosed/LSPosed)
41 | -- [GNU General Public License v3.0](https://github.com/LSPosed/LSPosed/blob/master/LICENSE)
42 |
43 | - [MIUIDock](https://github.com/ouhoukyo/MIUIDock)
44 | -- [MIT](https://github.com/ouhoukyo/MIUIDock/blob/master/LICENSE)
45 | - [MIDock](https://github.com/lamprose/MIDock)
46 | -- [MIT](https://github.com/lamprose/MIDock/blob/master/LICENSE)
47 | - [WINI](https://github.com/ouhoukyo/WINI)
48 | -- [MIT](https://github.com/ouhoukyo/WINI/blob/main/LICENSE)
49 |
50 | - [QNotified](https://github.com/ferredoxin/QNotified)
51 | -- [License v2](https://github.com/qwq233/License/blob/master/v2/LICENSE.md)
52 |
53 |
54 |
55 | ## License
56 |
57 | [GNU General Public License v3.0](LICENSE)
58 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /release
3 | /debug
4 |
--------------------------------------------------------------------------------
/app/libs/animation-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/animation-release.aar
--------------------------------------------------------------------------------
/app/libs/annotation-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/annotation-release.aar
--------------------------------------------------------------------------------
/app/libs/appcompat-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/appcompat-release.aar
--------------------------------------------------------------------------------
/app/libs/appcompat-resources-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/appcompat-resources-release.aar
--------------------------------------------------------------------------------
/app/libs/blur-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/blur-release.aar
--------------------------------------------------------------------------------
/app/libs/core-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/core-release.aar
--------------------------------------------------------------------------------
/app/libs/haptic-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/haptic-release.aar
--------------------------------------------------------------------------------
/app/libs/internal-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/internal-release.aar
--------------------------------------------------------------------------------
/app/libs/os-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/os-release.aar
--------------------------------------------------------------------------------
/app/libs/preference-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/preference-release.aar
--------------------------------------------------------------------------------
/app/libs/recyclerview-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/recyclerview-release.aar
--------------------------------------------------------------------------------
/app/libs/smooth-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/smooth-release.aar
--------------------------------------------------------------------------------
/app/libs/springback-release.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/libs/springback-release.aar
--------------------------------------------------------------------------------
/app/proguard-log.pro:
--------------------------------------------------------------------------------
1 | ##########################################################################################################
2 | # 作者:Sollyu
3 | # 日期:2020-11-02
4 | # 内容:发布版本移除日志,kotlin编译时带的而外信息,增强反调试难度
5 | # 使用:proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'proguard-log.pro'
6 | ##########################################################################################################
7 |
8 | ##########################################################################################################
9 | # 删除安卓日志
10 | -assumenosideeffects class android.util.Log {
11 | public static *** d(...);
12 | public static *** v(...);
13 | public static *** w(...);
14 | public static *** e(...);
15 | }
16 |
17 | ##########################################################################################################
18 | # 删除Kotlin编译时可能生成显示变量的方法
19 | -assumenosideeffects class kotlin.jvm.internal.Intrinsics {
20 | public static void checkExpressionValueIsNotNull(java.lang.Object, java.lang.String);
21 | public static void checkFieldIsNotNull(java.lang.Object, java.lang.String);
22 | public static void checkFieldIsNotNull(java.lang.Object, java.lang.String, java.lang.String);
23 | public static void checkNotNull(java.lang.Object);
24 | public static void checkNotNull(java.lang.Object, java.lang.String);
25 | public static void checkNotNullExpressionValue(java.lang.Object, java.lang.String);
26 | public static void checkNotNullParameter(java.lang.Object, java.lang.String);
27 | public static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
28 | public static void checkReturnedValueIsNotNull(java.lang.Object, java.lang.String);
29 | public static void throwUninitializedPropertyAccessException(java.lang.String);
30 | }
31 |
32 | ##########################################################################################################
33 | # 会暴露变量名称
34 | -assumenosideeffects class java.util.Objects {
35 | public static java.lang.Object requireNonNull(java.lang.Object, java.lang.String);
36 | }
37 |
38 | ##########################################################################################################
39 | # 删除slf4j的日志输出
40 | -assumenosideeffects interface org.slf4j.Logger {
41 | public void trace(...);
42 | public void debug(...);
43 | public void info(...);
44 | public void warn(...);
45 | public void error(...);
46 |
47 | public boolean isTraceEnabled(...);
48 | public boolean isDebugEnabled(...);
49 | public boolean isWarnEnabled(...);
50 | }
51 |
52 | -assumenosideeffects class org.slf4j.LoggerFactory {
53 | public static ** getLogger(...);
54 | }
--------------------------------------------------------------------------------
/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 |
23 | -repackageclasses "余空"
24 | -obfuscationdictionary dict.txt
25 | -classobfuscationdictionary dict.txt
26 | -packageobfuscationdictionary dict.txt
27 |
28 | -keep class com.yuk.miuiHomeR.MainHook {
29 | ();
30 | }
31 |
32 | -assumenosideeffects class kotlin.jvm.internal.Intrinsics {
33 | public static void check*(...);
34 | public static void throw*(...);
35 | }
36 |
37 | -keep class moralnorm.** {*;}
38 | -keep public class * extends moralnorm.**
39 |
40 | -keepclasseswithmembers class * {
41 | public (android.content.Context, android.util.AttributeSet);
42 | }
43 |
44 | -allowaccessmodification
45 | -overloadaggressively
--------------------------------------------------------------------------------
/app/src/.gitignore:
--------------------------------------------------------------------------------
1 | /androidTest
2 | /test
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
41 |
42 |
45 |
46 |
49 |
50 |
53 |
54 |
57 |
58 |
61 |
62 |
65 |
66 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
84 |
85 |
89 |
92 |
93 |
94 |
97 |
100 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | com.yuk.miuiHomeR.MainHook
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/Application.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR
2 |
3 | import android.content.Context
4 | import com.yuk.miuiHomeR.utils.PrefsUtils
5 | import com.yuk.miuiHomeR.utils.PrefsUtils.getSharedPrefs
6 | import com.yuk.miuiHomeR.utils.ktx.setLocale
7 | import java.util.Locale
8 |
9 | class Application : android.app.Application() {
10 |
11 | override fun attachBaseContext(base: Context?) {
12 | PrefsUtils.mSharedPreferences = base?.let { getSharedPrefs(it, false) }
13 | val locale: String? = PrefsUtils.mSharedPreferences?.getString("prefs_key_settings_language", "SYSTEM")
14 | if (locale != null) {
15 | if (base != null)
16 | super.attachBaseContext(setLocale(base, Locale.forLanguageTag(locale)))
17 | } else super.attachBaseContext(base)
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AllAppsContainerViewBlur.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.os.Build
4 | import android.view.View
5 | import android.widget.FrameLayout
6 | import android.widget.RelativeLayout
7 | import android.widget.ViewSwitcher
8 | import androidx.annotation.RequiresApi
9 | import com.github.kyuubiran.ezxhelper.utils.findMethod
10 | import com.github.kyuubiran.ezxhelper.utils.hookAfter
11 | import com.yuk.miuiHomeR.mPrefsMap
12 | import com.yuk.miuiHomeR.utils.ktx.findClass
13 | import com.yuk.miuiHomeR.utils.ktx.getCornerRadiusTop
14 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
15 | import com.zhenxiang.blur.BlurFrameLayout
16 | import com.zhenxiang.blur.model.CornersRadius
17 |
18 | @RequiresApi(Build.VERSION_CODES.S)
19 | object AllAppsContainerViewBlur : BaseHook() {
20 | override fun init() {
21 |
22 | if (!mPrefsMap.getBoolean("home_all_apps_blur")) return
23 | findMethod("com.miui.home.launcher.allapps.BaseAllAppsContainerView".findClass(), true) {
24 | name == "onFinishInflate"
25 | }.hookAfter { hookParam ->
26 | val mCategoryContainer = hookParam.thisObject.getObjectField("mCategoryContainer") as ViewSwitcher
27 | val appsView = mCategoryContainer.parent as RelativeLayout
28 | val blur = BlurFrameLayout(mCategoryContainer.context)
29 | val radius = getCornerRadiusTop().toFloat()
30 | blur.blurController.apply {
31 | cornerRadius = CornersRadius.custom(radius, radius, 0f, 0f)
32 | }
33 | val view = View(mCategoryContainer.context)
34 | blur.addView(view)
35 | (view.layoutParams as FrameLayout.LayoutParams).apply {
36 | width = FrameLayout.LayoutParams.MATCH_PARENT
37 | height = FrameLayout.LayoutParams.MATCH_PARENT
38 | }
39 | appsView.addView(blur, 0)
40 | findMethod("com.miui.home.launcher.allapps.BaseAllAppsContainerView".findClass(), true) {
41 | name == "onResume"
42 | }.hookAfter {
43 | blur.refreshDrawableState()
44 | }
45 | }
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AllowMoveAllWidgetToMinus.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.getObject
5 | import com.github.kyuubiran.ezxhelper.utils.getObjectOrNull
6 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
7 | import com.github.kyuubiran.ezxhelper.utils.invokeMethodAuto
8 | import com.yuk.miuiHomeR.mPrefsMap
9 | import com.yuk.miuiHomeR.utils.ktx.callMethod
10 |
11 | object AllowMoveAllWidgetToMinus : BaseHook() {
12 | override fun init() {
13 |
14 | if (!mPrefsMap.getBoolean("home_widget_to_minus")) return
15 | try {
16 | findMethod("com.miui.home.launcher.widget.MIUIWidgetHelper") {
17 | name == "canDragToPa" && parameterCount == 2
18 | }.hookBefore {
19 | val dragInfo = it.args[1].invokeMethodAuto("getDragInfo")
20 | val i = dragInfo?.getObject("spanX")
21 | val launcherCallbacks = it.args[0].invokeMethodAuto("getLauncherCallbacks")
22 | val dragController = it.args[0].invokeMethodAuto("getDragController")
23 | val isDraggingFromAssistant = dragController?.callMethod("isDraggingFromAssistant") as Boolean
24 | val isDraggingToAssistant = dragController.callMethod("isDraggingToAssistant") as Boolean
25 | it.result = launcherCallbacks != null && !isDraggingFromAssistant && !isDraggingToAssistant && i != 1
26 | }
27 | } catch (e: Exception) {
28 | findMethod("com.miui.home.launcher.Workspace") {
29 | name == "canDragToPa"
30 | }.hookBefore {
31 | val currentDragObject = it.thisObject.getObjectOrNull("mDragController")?.invokeMethodAuto("getCurrentDragObject")
32 | val dragInfo = currentDragObject?.invokeMethodAuto("getDragInfo")
33 | val i = dragInfo?.getObject("spanX")
34 | val launcherCallbacks = it.thisObject.getObjectOrNull("mLauncher")?.invokeMethodAuto("getLauncherCallbacks")
35 | val isDraggingFromAssistant = it.thisObject.getObjectOrNull("mDragController")?.callMethod("isDraggingFromAssistant") as Boolean
36 | val isDraggingToAssistant = it.thisObject.getObjectOrNull("mDragController")?.callMethod("isDraggingToAssistant") as Boolean
37 | it.result = launcherCallbacks != null && !isDraggingFromAssistant && !isDraggingToAssistant && i != 1
38 | }
39 | }
40 |
41 | }
42 | }
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AlwaysBlurWallpaper.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
5 | import com.yuk.miuiHomeR.mPrefsMap
6 |
7 | object AlwaysBlurWallpaper : BaseHook() {
8 | override fun init() {
9 |
10 | if (!mPrefsMap.getBoolean("home_blur_wallpaper")) return
11 | val value = mPrefsMap.getInt("home_blur_radius", 100)
12 | findMethod("com.miui.home.launcher.common.BlurUtils") {
13 | name == "fastBlur" && parameterCount == 4
14 | }.hookBefore {
15 | it.args[0] = value.toFloat() / 100
16 | it.args[2] = true
17 | }
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AlwaysShowMiuiWidget.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookAfter
5 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
6 | import com.github.kyuubiran.ezxhelper.utils.hookMethod
7 | import com.github.kyuubiran.ezxhelper.utils.putObject
8 | import com.yuk.miuiHomeR.mPrefsMap
9 | import de.robv.android.xposed.XC_MethodHook
10 |
11 | object AlwaysShowMiuiWidget : BaseHook() {
12 | override fun init() {
13 |
14 | if (!mPrefsMap.getBoolean("home_widget_miui")) return
15 | var hook1: XC_MethodHook.Unhook? = null
16 | var hook2: XC_MethodHook.Unhook? = null
17 | try {
18 | findMethod("com.miui.home.launcher.widget.WidgetsVerticalAdapter") {
19 | name == "buildAppWidgetsItems"
20 | }
21 | } catch (e: Exception) {
22 | findMethod("com.miui.home.launcher.widget.BaseWidgetsVerticalAdapter") {
23 | name == "buildAppWidgetsItems"
24 | }
25 | }.hookMethod {
26 | before {
27 | hook1 = findMethod("com.miui.home.launcher.widget.MIUIAppWidgetInfo") {
28 | name == "initMiuiAttribute" && parameterCount == 1
29 | }.hookAfter {
30 | it.thisObject.putObject("isMIUIWidget", false)
31 | }
32 | hook2 = findMethod("com.miui.home.launcher.MIUIWidgetUtil") {
33 | name == "isMIUIWidgetSupport"
34 | }.hookBefore {
35 | it.result = false
36 | }
37 | }
38 | after {
39 | hook1?.unhook()
40 | hook2?.unhook()
41 | }
42 | }
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AlwaysShowStatusClock.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
5 | import com.yuk.miuiHomeR.mPrefsMap
6 |
7 | object AlwaysShowStatusClock : BaseHook() {
8 | override fun init() {
9 |
10 | if (!mPrefsMap.getBoolean("home_show_status_clock")) return
11 | try {
12 | findMethod("com.miui.home.launcher.Workspace") {
13 | name == "isScreenHasClockGadget" && parameterCount == 1
14 | }
15 | } catch (e: Exception) {
16 | findMethod("com.miui.home.launcher.Workspace") {
17 | name == "isScreenHasClockWidget" && parameterCount == 1
18 | }
19 | }.hookReturnConstant(false)
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AnimDurationRatio.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
5 | import com.yuk.miuiHomeR.mPrefsMap
6 |
7 | object AnimDurationRatio : BaseHook() {
8 | override fun init() {
9 |
10 | val value1 = mPrefsMap.getInt("home_anim_ratio", 150).toFloat() / 100f
11 | val value2 = mPrefsMap.getInt("home_anim_ratio_recent", 130).toFloat() / 100f
12 | findMethod("com.miui.home.recents.util.RectFSpringAnim") {
13 | name == "getModifyResponse"
14 | }.hookBefore {
15 | it.result = it.args[0] as Float * value1
16 | }
17 |
18 | findMethod("com.miui.home.launcher.common.DeviceLevelUtils") {
19 | name == "getDeviceLevelTransitionAnimRatio"
20 | }.hookBefore {
21 | it.result = value2
22 | }
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/AppDrawer.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.view.View
4 | import com.github.kyuubiran.ezxhelper.utils.findMethod
5 | import com.github.kyuubiran.ezxhelper.utils.hookAfter
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ktx.callMethodAs
8 | import com.yuk.miuiHomeR.utils.ktx.findClass
9 | import com.yuk.miuiHomeR.utils.ktx.getObjectFieldAs
10 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
11 |
12 | object AppDrawer : BaseHook() {
13 | override fun init() {
14 |
15 | if (mPrefsMap.getBoolean("home_hide_category_all")) {
16 | try {
17 | findMethod("com.miui.home.launcher.allapps.category.BaseAllAppsCategoryListContainer") {
18 | name == "buildSortCategoryList"
19 | }
20 | } catch (e: Exception) {
21 | findMethod("com.miui.home.launcher.allapps.category.AllAppsCategoryListContainer") {
22 | name == "buildSortCategoryList"
23 | }
24 | }.hookAfter {
25 | val list = it.result as ArrayList<*>
26 | if (list.size > 1) {
27 | list.removeAt(0)
28 | it.result = list
29 | }
30 | }
31 | }
32 |
33 | if (mPrefsMap.getBoolean("home_hide_category_paging_edit")) {
34 | "com.miui.home.launcher.allapps.AllAppsGridAdapter".hookAfterMethod(
35 | "onBindViewHolder", "com.miui.home.launcher.allapps.AllAppsGridAdapter.ViewHolder".findClass(), Int::class.javaPrimitiveType
36 | ) {
37 | if (it.args[0].callMethodAs("getItemViewType") == 64) {
38 | it.args[0].getObjectFieldAs("itemView").visibility = View.INVISIBLE
39 | }
40 | }
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/BaseHook.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | abstract class BaseHook {
4 | var isInit: Boolean = false
5 | abstract fun init()
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/BigIconCorner.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
5 | import com.yuk.miuiHomeR.mPrefsMap
6 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
7 |
8 | object BigIconCorner : BaseHook() {
9 | override fun init() {
10 |
11 | if (!mPrefsMap.getBoolean("big_icon_corner")) return
12 | findMethod("com.miui.home.launcher.bigicon.BigIconUtil") {
13 | name == "getCroppedFromCorner" && parameterCount == 4
14 | }.hookBefore {
15 | it.args[0] = 2
16 | it.args[1] = 2
17 | }
18 |
19 | findMethod(
20 | "com.miui.home.launcher.maml.MaMlHostView"
21 | ) {
22 | name == "getCornerRadius"
23 | }.hookBefore {
24 | it.result = it.thisObject.getObjectField("mEnforcedCornerRadius") as Float
25 | }
26 |
27 | findMethod("com.miui.home.launcher.maml.MaMlHostView") {
28 | name == "computeRoundedCornerRadius" && parameterCount == 1
29 | }.hookBefore {
30 | it.result = it.thisObject.getObjectField("mEnforcedCornerRadius") as Float
31 | }
32 |
33 | findMethod("com.miui.home.launcher.LauncherAppWidgetHostView") {
34 | name == "computeRoundedCornerRadius" && parameterCount == 1
35 | }.hookBefore {
36 | it.result = it.thisObject.getObjectField("mEnforcedCornerRadius") as Float
37 | }
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/BlurLevel.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.app.Activity
4 | import com.github.kyuubiran.ezxhelper.utils.findMethod
5 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
6 | import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
7 | import com.yuk.miuiHomeR.mPrefsMap
8 | import com.yuk.miuiHomeR.utils.ktx.callStaticMethod
9 | import com.yuk.miuiHomeR.utils.ktx.findClass
10 | import com.yuk.miuiHomeR.utils.ktx.hookAfterAllMethods
11 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
12 |
13 | object BlurLevel : BaseHook() {
14 | override fun init() {
15 |
16 | val blurLevel = mPrefsMap.getStringAsInt("recent_blur", 2)
17 | if (blurLevel == 4) {
18 | findMethod("com.miui.home.launcher.common.BlurUtils") {
19 | name == "getBlurType"
20 | }.hookReturnConstant(0)
21 | findMethod("com.miui.home.launcher.common.BlurUtils") {
22 | name == "isUseCompleteBlurOnDev"
23 | }.hookReturnConstant(false)
24 | "com.miui.home.launcher.common.DeviceLevelUtils".hookBeforeMethod("isUseSimpleAnim") {
25 | it.result = true
26 | }
27 | } else {
28 | "com.miui.home.launcher.common.DeviceLevelUtils".hookBeforeMethod("isUseSimpleAnim") {
29 | it.result = false
30 | }
31 | findMethod("com.miui.home.launcher.common.BlurUtils") {
32 | name == "getBlurType"
33 | }.hookBefore {
34 | when (blurLevel) {
35 | 0 -> it.result = 2
36 | 2 -> it.result = 1
37 | 3 -> it.result = 0
38 | }
39 | }
40 | findMethod("com.miui.home.launcher.common.BlurUtils") {
41 | name == "isUseCompleteBlurOnDev"
42 | }.hookBefore {
43 | when (blurLevel) {
44 | 1 -> it.result = true
45 | }
46 | }
47 | }
48 | if (blurLevel == 0 && mPrefsMap.getBoolean("complete_blur_fix")) {
49 | val blurClass = "com.miui.home.launcher.common.BlurUtils".findClass()
50 | val navStubViewClass = "com.miui.home.recents.NavStubView".findClass()
51 | val applicationClass = "com.miui.home.launcher.Application".findClass()
52 | navStubViewClass.hookAfterAllMethods("onTouchEvent") {
53 | val mLauncher = applicationClass.callStaticMethod("getLauncher") as Activity
54 | blurClass.callStaticMethod("fastBlur", 1.0f, mLauncher.window, true, 500L)
55 | }
56 | }
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/BlurRadius.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.loadClass
4 | import com.yuk.miuiHomeR.mPrefsMap
5 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeAllMethods
6 |
7 | object BlurRadius : BaseHook() {
8 | override fun init() {
9 |
10 | val value = mPrefsMap.getInt("home_blur_radius", 100).toFloat() / 100
11 | if (value == 1f) return
12 | val blurUtilsClass = loadClass("com.miui.home.launcher.common.BlurUtils")
13 | blurUtilsClass.hookBeforeAllMethods("fastBlur") {
14 | it.args[0] = it.args[0] as Float * value
15 | }
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/CloseFolderWhenLaunchedApp.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.view.View
4 | import com.yuk.miuiHomeR.mPrefsMap
5 | import com.yuk.miuiHomeR.utils.ktx.callMethod
6 | import com.yuk.miuiHomeR.utils.ktx.getBooleanField
7 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
8 |
9 | object CloseFolderWhenLaunchedApp : BaseHook() {
10 | override fun init() {
11 |
12 | if (!mPrefsMap.getBoolean("home_close_folder")) return
13 | "com.miui.home.launcher.Launcher".hookAfterMethod(
14 | "launch", "com.miui.home.launcher.ShortcutInfo", View::class.java
15 | ) {
16 | val mHasLaunchedAppFromFolder = it.thisObject.getBooleanField("mHasLaunchedAppFromFolder")
17 | if (mHasLaunchedAppFromFolder) it.thisObject.callMethod("closeFolder")
18 | }
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/DisableRecentViewWallpaperDarken.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
5 | import com.github.kyuubiran.ezxhelper.utils.putObject
6 | import com.yuk.miuiHomeR.mPrefsMap
7 |
8 | object DisableRecentViewWallpaperDarken : BaseHook() {
9 | override fun init() {
10 |
11 | if (!mPrefsMap.getBoolean("home_disable_darken")) return
12 | findMethod("com.miui.home.recents.DimLayer") {
13 | name == "dim" && parameterCount == 3
14 | }.hookBefore {
15 | it.args[0] = 0.0f
16 | it.thisObject.putObject("mCurrentAlpha", 0.0f)
17 | }
18 |
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/Dock.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.FrameLayout
8 | import com.github.kyuubiran.ezxhelper.init.InitFields.appContext
9 | import com.github.kyuubiran.ezxhelper.utils.hookAllConstructorAfter
10 | import com.yuk.miuiHomeR.mPrefsMap
11 | import com.yuk.miuiHomeR.utils.ktx.atLeastAndroidS
12 | import com.yuk.miuiHomeR.utils.ktx.callMethod
13 | import com.yuk.miuiHomeR.utils.ktx.dp2px
14 | import com.yuk.miuiHomeR.utils.ktx.findClass
15 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
16 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
17 | import com.zhenxiang.blur.BlurFrameLayout
18 | import com.zhenxiang.blur.model.CornersRadius
19 | import de.robv.android.xposed.XposedHelpers
20 |
21 | object Dock : BaseHook() {
22 | override fun init() {
23 |
24 | if (!mPrefsMap.getBoolean("dock_hook_enabled")) return
25 | var isShowEditPanel = false
26 | var isFolderShowing = false
27 | val launcherClass = "com.miui.home.launcher.Launcher".findClass()
28 | val launcherStateClass = "com.miui.home.launcher.LauncherState".findClass()
29 | val folderInfo = "com.miui.home.launcher.FolderInfo".findClass()
30 | val blurClass = "com.miui.home.launcher.common.BlurUtils".findClass()
31 | val mDockHeight = dp2px(mPrefsMap.getInt("home_dock_height", 98).toFloat())
32 | val mDockMargin = dp2px(mPrefsMap.getInt("home_dock_margin", 10).toFloat())
33 | val mDockBottomMargin = dp2px(mPrefsMap.getInt("home_dock_bottom_margin", 13).toFloat())
34 | val mDockCorner = dp2px(mPrefsMap.getInt("home_dock_corner", 25).toFloat())
35 |
36 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod(
37 | "calcHotSeatsMarginTop", Context::class.java, Boolean::class.javaPrimitiveType
38 | ) {
39 | it.result = dp2px(mPrefsMap.getInt("home_dock_top_margin", 20).toFloat())
40 | }
41 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod(
42 | "getWorkspaceIndicatorMarginBottom"
43 | ) {
44 | it.result = dp2px(mPrefsMap.getInt("home_icon_bottom_margin", 110).toFloat())
45 | }
46 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod(
47 | "calcHotSeatsMarginBottom", Context::class.java, Boolean::class.java, Boolean::class.java
48 | ) {
49 | it.result = dp2px(mPrefsMap.getInt("home_dock_icon_bottom_margin", -8).toFloat())
50 | }
51 |
52 | // Dock
53 | if (atLeastAndroidS() && mPrefsMap.getBoolean("home_dock_blur")) {
54 | hookAllConstructorAfter("com.miui.home.launcher.Launcher") {
55 | var mDockBlur = XposedHelpers.getAdditionalInstanceField(it.thisObject, "mDockBlur")
56 | if (mDockBlur != null) return@hookAllConstructorAfter
57 | mDockBlur = BlurFrameLayout(appContext)
58 | XposedHelpers.setAdditionalInstanceField(it.thisObject, "mDockBlur", mDockBlur)
59 | }
60 | launcherClass.hookAfterMethod("onCreate", Bundle::class.java) {
61 | val mSearchBarContainer = it.thisObject.callMethod("getSearchBarContainer") as FrameLayout
62 | val mSearchEdgeLayout = mSearchBarContainer.parent as FrameLayout
63 | val mDockBlur = XposedHelpers.getAdditionalInstanceField(it.thisObject, "mDockBlur") as BlurFrameLayout
64 | val lp = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, mDockHeight)
65 | lp.gravity = Gravity.BOTTOM
66 | lp.setMargins(mDockMargin, 0, mDockMargin, mDockBottomMargin)
67 | mDockBlur.blurController.apply {
68 | cornerRadius = CornersRadius.all(mDockCorner.toFloat())
69 | }
70 | mDockBlur.layoutParams = lp
71 | mSearchEdgeLayout.addView(mDockBlur, 0)
72 | launcherClass.hookAfterMethod("isFolderShowing") { hookParam ->
73 | isFolderShowing = hookParam.result as Boolean
74 | }
75 | launcherClass.hookAfterMethod("showEditPanel", Boolean::class.java) { hookParam ->
76 | isShowEditPanel = hookParam.args[0] as Boolean
77 | if (isShowEditPanel) mDockBlur.visibility = View.GONE
78 | else mDockBlur.visibility = View.VISIBLE
79 | }
80 | launcherClass.hookAfterMethod("openFolder", folderInfo, View::class.java) {
81 | mDockBlur.visibility = View.GONE
82 | }
83 | launcherClass.hookAfterMethod("closeFolder", Boolean::class.java) {
84 | if (!isShowEditPanel) mDockBlur.visibility = View.VISIBLE
85 | }
86 | blurClass.hookAfterMethod(
87 | "fastBlurWhenEnterRecents", launcherClass, launcherStateClass, Boolean::class.java
88 | ) {
89 | mDockBlur.visibility = View.GONE
90 | }
91 | }
92 | launcherClass.hookAfterMethod("onStateSetStart", launcherStateClass) {
93 | val mDockBlur = XposedHelpers.getAdditionalInstanceField(it.thisObject, "mDockBlur") as BlurFrameLayout
94 | if ("LauncherState" == it.args[0].javaClass.simpleName && !isFolderShowing && !isShowEditPanel) {
95 | mDockBlur.visibility = View.VISIBLE
96 | } else mDockBlur.visibility = View.GONE
97 | }
98 | }
99 |
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/DoubleTapController.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.content.Context
4 | import android.os.SystemClock
5 | import android.view.MotionEvent
6 | import android.view.ViewConfiguration
7 |
8 | class DoubleTapController internal constructor(mContext: Context) {
9 |
10 | private val maxDuration: Long = 500
11 | private var mActionDownRawX: Float = 0f
12 | private var mActionDownRawY: Float = 0f
13 | private var mClickCount: Int = 0
14 | private var mFirstClickRawX: Float = 0f
15 | private var mFirstClickRawY: Float = 0f
16 | private var mLastClickTime: Long = 0
17 | private val mTouchSlop: Int = ViewConfiguration.get(mContext).scaledTouchSlop * 2
18 |
19 | fun isDoubleTapEvent(motionEvent: MotionEvent): Boolean {
20 | val action = motionEvent.actionMasked
21 | return when {
22 | action == MotionEvent.ACTION_DOWN -> {
23 | mActionDownRawX = motionEvent.rawX
24 | mActionDownRawY = motionEvent.rawY
25 | false
26 | }
27 |
28 | action != MotionEvent.ACTION_UP -> false
29 | else -> {
30 | val rawX = motionEvent.rawX
31 | val rawY = motionEvent.rawY
32 | if (kotlin.math.abs(rawX - mActionDownRawX) <= mTouchSlop.toFloat() && kotlin.math.abs(
33 | rawY - mActionDownRawY
34 | ) <= mTouchSlop.toFloat()
35 | ) {
36 | if (SystemClock.elapsedRealtime() - mLastClickTime > maxDuration || rawY - mFirstClickRawY > mTouchSlop.toFloat() || rawX - mFirstClickRawX > mTouchSlop.toFloat()) mClickCount =
37 | 0
38 | mClickCount++
39 | if (mClickCount == 1) {
40 | mFirstClickRawX = rawX
41 | mFirstClickRawY = rawY
42 | mLastClickTime = SystemClock.elapsedRealtime()
43 | return false
44 | } else if (kotlin.math.abs(rawY - mFirstClickRawY) <= mTouchSlop.toFloat() && kotlin.math.abs(
45 | rawX - mFirstClickRawX
46 | ) <= mTouchSlop.toFloat() && SystemClock.elapsedRealtime() - mLastClickTime <= maxDuration
47 | ) {
48 | mClickCount = 0
49 | return true
50 | }
51 | }
52 | mClickCount = 0
53 | false
54 | }
55 | }
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/DoubleTapToSleep.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.view.MotionEvent
6 | import com.github.kyuubiran.ezxhelper.utils.findMethod
7 | import com.github.kyuubiran.ezxhelper.utils.getObject
8 | import com.github.kyuubiran.ezxhelper.utils.hookAllConstructorAfter
9 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
10 | import com.github.kyuubiran.ezxhelper.utils.invokeMethodAuto
11 | import com.yuk.miuiHomeR.mPrefsMap
12 | import de.robv.android.xposed.XposedHelpers
13 |
14 | object DoubleTapToSleep : BaseHook() {
15 | override fun init() {
16 |
17 | if (!mPrefsMap.getBoolean("home_double_sleep")) return
18 | hookAllConstructorAfter("com.miui.home.launcher.Workspace") {
19 | var mDoubleTapControllerEx = XposedHelpers.getAdditionalInstanceField(it.thisObject, "mDoubleTapControllerEx")
20 | if (mDoubleTapControllerEx != null) return@hookAllConstructorAfter
21 | mDoubleTapControllerEx = DoubleTapController((it.args[0] as Context))
22 | XposedHelpers.setAdditionalInstanceField(it.thisObject, "mDoubleTapControllerEx", mDoubleTapControllerEx)
23 | }
24 | findMethod("com.miui.home.launcher.Workspace") {
25 | name == "dispatchTouchEvent" && parameterCount == 1
26 | }.hookBefore {
27 | val mDoubleTapControllerEx = XposedHelpers.getAdditionalInstanceField(it.thisObject, "mDoubleTapControllerEx") as DoubleTapController
28 | if (!mDoubleTapControllerEx.isDoubleTapEvent(it.args[0] as MotionEvent)) return@hookBefore
29 | val mCurrentScreenIndex = it.thisObject.getObject("mCurrentScreenIndex")
30 | val cellLayout = it.thisObject.invokeMethodAuto("getCellLayout", mCurrentScreenIndex)
31 | if (cellLayout != null) if (cellLayout.invokeMethodAuto("lastDownOnOccupiedCell") as Boolean) return@hookBefore
32 | if (it.thisObject.invokeMethodAuto("isInNormalEditingMode") as Boolean) return@hookBefore
33 | val context = it.thisObject.invokeMethodAuto("getContext") as Context
34 | context.sendBroadcast(
35 | Intent("com.miui.app.ExtraStatusBarManager.action_TRIGGER_TOGGLE").putExtra(
36 | "com.miui.app.ExtraStatusBarManager.extra_TOGGLE_ID", 10
37 | )
38 | )
39 | }
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/EnableBlurWhenOpenFolder.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import android.view.View
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ktx.callStaticMethod
8 | import com.yuk.miuiHomeR.utils.ktx.findClass
9 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
10 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
11 | import com.yuk.miuiHomeR.utils.ktx.isAlpha
12 |
13 | object EnableBlurWhenOpenFolder : BaseHook() {
14 | override fun init() {
15 |
16 | if (mPrefsMap.getStringAsInt(
17 | "recent_blur", 0
18 | ) == 4 || !mPrefsMap.getBoolean("home_folder_blur")
19 | ) {
20 | if (isAlpha()) {
21 | "com.miui.home.launcher.common.BlurUtils".hookBeforeMethod("isUserBlurWhenOpenFolder") {
22 | it.result = false
23 | }
24 | }
25 | } else {
26 | if (mPrefsMap.getBoolean("home_folder_blur")) {
27 | if (isAlpha()) {
28 | "com.miui.home.launcher.common.BlurUtils".hookBeforeMethod("isUserBlurWhenOpenFolder") {
29 | it.result = true
30 | }
31 | } else {
32 | val blurClass = "com.miui.home.launcher.common.BlurUtils".findClass()
33 | val folderInfo = "com.miui.home.launcher.FolderInfo".findClass()
34 | val launcherClass = "com.miui.home.launcher.Launcher".findClass()
35 | val launcherStateClass = "com.miui.home.launcher.LauncherState".findClass()
36 | val cancelShortcutMenuReasonClass = "com.miui.home.launcher.shortcuts.CancelShortcutMenuReason".findClass()
37 | launcherClass.hookAfterMethod("onCreate", Bundle::class.java) {
38 | val activity = it.thisObject as Activity
39 | var isFolderShowing = false
40 | var isShowEditPanel = false
41 | launcherClass.hookAfterMethod("isFolderShowing") { hookParam ->
42 | isFolderShowing = hookParam.result as Boolean
43 | }
44 | launcherClass.hookAfterMethod("showEditPanel", Boolean::class.java) { hookParam ->
45 | isShowEditPanel = hookParam.args[0] as Boolean
46 | }
47 | launcherClass.hookAfterMethod("openFolder", folderInfo, View::class.java) {
48 | blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true)
49 | }
50 | launcherClass.hookAfterMethod("closeFolder", Boolean::class.java) {
51 | if (isShowEditPanel) blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
52 | else blurClass.callStaticMethod("fastBlur", 0.0f, activity.window, true, 300L)
53 | }
54 | launcherClass.hookAfterMethod("cancelShortcutMenu", Int::class.java, cancelShortcutMenuReasonClass) {
55 | if (isFolderShowing) blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
56 | }
57 | blurClass.hookAfterMethod(
58 | "fastBlurWhenStartOpenOrCloseApp", Boolean::class.java, launcherClass
59 | ) { hookParam ->
60 | if (isFolderShowing) hookParam.result = blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
61 | else if (isShowEditPanel) hookParam.result = blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
62 | }
63 | blurClass.hookAfterMethod(
64 | "fastBlurWhenFinishOpenOrCloseApp", launcherClass
65 | ) { hookParam ->
66 | if (isFolderShowing) hookParam.result = blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
67 | else if (isShowEditPanel) hookParam.result = blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
68 | }
69 | blurClass.hookAfterMethod(
70 | "fastBlurWhenExitRecents", launcherClass, launcherStateClass, Boolean::class.java
71 | ) { hookParam ->
72 | if (isFolderShowing) hookParam.result = blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
73 | else if (isShowEditPanel) hookParam.result = blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 0L)
74 | }
75 | launcherClass.hookAfterMethod("onGesturePerformAppToHome") {
76 | if (isFolderShowing) blurClass.callStaticMethod("fastBlur", 1.0f, activity.window, true, 300L)
77 | }
78 | }
79 | }
80 | }
81 | }
82 |
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/FoldDeviceDock.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.content.Context
4 | import com.github.kyuubiran.ezxhelper.utils.findMethod
5 | import com.github.kyuubiran.ezxhelper.utils.hookMethod
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
8 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
9 | import de.robv.android.xposed.XC_MethodHook
10 |
11 | object FoldDeviceDock : BaseHook() {
12 | override fun init() {
13 |
14 | if (!mPrefsMap.getBoolean("home_fold_dock")) return
15 | var hook1: XC_MethodHook.Unhook? = null
16 | var hook2: XC_MethodHook.Unhook? = null
17 | var hook3: XC_MethodHook.Unhook? = null
18 | findMethod("com.miui.home.launcher.hotseats.HotSeats") {
19 | name == "initContent"
20 | }.hookMethod {
21 | before {
22 | hook1 = "com.miui.home.launcher.DeviceConfig".hookBeforeMethod(
23 | "isFoldDevice"
24 | ) { hookParam ->
25 | hookParam.result = true
26 | }
27 | }
28 | after {
29 | hook1?.unhook()
30 | }
31 | }
32 |
33 | try {
34 | findMethod("com.miui.home.launcher.hotseats.HotSeats") {
35 | name == "updateContent"
36 | }
37 | } catch (e: Exception) {
38 | findMethod("com.miui.home.launcher.hotseats.HotSeats") {
39 | name == "updateContentView"
40 | }
41 | }.hookMethod {
42 | before {
43 | hook2 = "com.miui.home.launcher.Application".hookBeforeMethod(
44 | "isInFoldLargeScreen"
45 | ) { hookParam ->
46 | hookParam.result = true
47 | }
48 | }
49 | after {
50 | hook2?.unhook()
51 |
52 | }
53 | }
54 |
55 | findMethod("com.miui.home.launcher.hotseats.HotSeats") {
56 | name == "isNeedUpdateItemInfo"
57 | }.hookMethod {
58 | before {
59 | hook2 = "com.miui.home.launcher.Application".hookBeforeMethod(
60 | "isInFoldLargeScreen"
61 | ) { hookParam ->
62 | hookParam.result = true
63 | }
64 | }
65 | after {
66 | hook2?.unhook()
67 | }
68 | }
69 |
70 | findMethod("com.miui.home.launcher.hotseats.HotSeatsListRecentsAppProvider\$1") {
71 | name == "handleMessage" && parameterCount == 1
72 | }.hookMethod {
73 | before {
74 | hook3 = "com.miui.home.launcher.Application".hookBeforeMethod("isInFoldLargeScreen") { hookParam -> hookParam.result = true }
75 | }
76 | after { hook3?.unhook() }
77 | }
78 |
79 | "com.miui.home.launcher.DeviceConfig".hookAfterMethod("getHotseatMaxCount") {
80 | it.result = mPrefsMap.getInt("home_fold_dock_hotseat", 3)
81 | }
82 |
83 | "com.miui.home.launcher.hotseats.HotSeatsListRecentsAppProvider".hookBeforeMethod("getLimitCount") {
84 | it.result = mPrefsMap.getInt("home_fold_dock_run", 2)
85 | }
86 |
87 | "com.miui.home.launcher.allapps.LauncherMode".hookBeforeMethod("isHomeSupportSearchBar", Context::class.java) {
88 | it.result = false
89 | }
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/FolderAnim.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookMethod
5 | import com.yuk.miuiHomeR.mPrefsMap
6 | import com.yuk.miuiHomeR.utils.ktx.findClass
7 | import com.yuk.miuiHomeR.utils.ktx.findClassOrNull
8 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
9 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
10 | import de.robv.android.xposed.XC_MethodHook
11 |
12 | object FolderAnim : BaseHook() {
13 | override fun init() {
14 |
15 | if (!mPrefsMap.getBoolean("home_folder_anim")) return
16 | val value1 = mPrefsMap.getInt("home_folder_anim_1", 90).toFloat() / 100
17 | val value2 = mPrefsMap.getInt("home_folder_anim_2", 30).toFloat() / 100
18 | val value3 = mPrefsMap.getInt("home_folder_anim_3", 99).toFloat() / 100
19 | val value4 = mPrefsMap.getInt("home_folder_anim_4", 24).toFloat() / 100
20 | val mSpringAnimator = "com.miui.home.launcher.animate.SpringAnimator".findClass()
21 | var hook1: XC_MethodHook.Unhook? = null
22 | var hook2: XC_MethodHook.Unhook? = null
23 | for (i in 47..60) {
24 | val launcherClass = "com.miui.home.launcher.Launcher$$i".findClassOrNull()
25 | if (launcherClass != null) {
26 | for (field in launcherClass.declaredFields) {
27 | if (field.name == "val\$folderInfo") {
28 | findMethod(launcherClass) {
29 | name == "run"
30 | }.hookMethod {
31 | before {
32 | hook1 = mSpringAnimator.hookBeforeMethod(
33 | "setDampingResponse", Float::class.javaPrimitiveType, Float::class.javaPrimitiveType
34 | ) {
35 | it.args[0] = value1
36 | it.args[1] = value2
37 | }
38 | }
39 | after {
40 | hook1?.unhook()
41 | }
42 | }
43 | break
44 | }
45 | }
46 | }
47 | }
48 |
49 | "com.miui.home.launcher.Launcher".hookBeforeMethod("closeFolder", Boolean::class.java) {
50 | if (it.args[0] == true) {
51 | hook2 = mSpringAnimator.hookBeforeMethod(
52 | "setDampingResponse", Float::class.javaPrimitiveType, Float::class.javaPrimitiveType
53 | ) { hookParam ->
54 | hookParam.args[0] = value3
55 | hookParam.args[1] = value4
56 | }
57 | }
58 | }
59 | "com.miui.home.launcher.Launcher".hookAfterMethod("closeFolder", Boolean::class.java) {
60 | hook2?.unhook()
61 | }
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/FolderColumnsCount.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.view.ViewGroup
4 | import android.widget.GridView
5 | import com.github.kyuubiran.ezxhelper.utils.loadClass
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ktx.hookAfterAllMethods
8 | import de.robv.android.xposed.XposedHelpers
9 |
10 | object FolderColumnsCount : BaseHook() {
11 | override fun init() {
12 |
13 | val value = mPrefsMap.getInt("home_folder_columns", 3)
14 | if (value == 3) return
15 | loadClass("com.miui.home.launcher.Folder").hookAfterAllMethods(
16 | "bind"
17 | ) {
18 | val columns: Int = value
19 | val mContent = XposedHelpers.getObjectField(it.thisObject, "mContent") as GridView
20 | mContent.numColumns = columns
21 | if (mPrefsMap.getBoolean("home_folder_width") && (columns > 3)) {
22 | mContent.setPadding(0, 0, 0, 0)
23 | val lp = mContent.layoutParams
24 | lp.width = ViewGroup.LayoutParams.MATCH_PARENT
25 | mContent.layoutParams = lp
26 | }
27 | if (columns > 3) {
28 | val mBackgroundView = XposedHelpers.getObjectField(it.thisObject, "mBackgroundView") as ViewGroup
29 | mBackgroundView.setPadding(
30 | mBackgroundView.paddingLeft / 3, mBackgroundView.paddingTop, mBackgroundView.paddingRight / 3, mBackgroundView.paddingBottom
31 | )
32 | }
33 | }
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/FolderVerticalPadding.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.widget.GridView
4 | import com.github.kyuubiran.ezxhelper.utils.loadClass
5 | import com.yuk.miuiHomeR.mPrefsMap
6 | import com.yuk.miuiHomeR.utils.ktx.dp2px
7 | import com.yuk.miuiHomeR.utils.ktx.hookAfterAllMethods
8 | import de.robv.android.xposed.XposedHelpers
9 |
10 | object FolderVerticalPadding : BaseHook() {
11 | override fun init() {
12 |
13 | val verticalPadding = mPrefsMap.getInt("home_folder_vertical_padding", 0)
14 | if (verticalPadding <= 0) return
15 | loadClass("com.miui.home.launcher.Folder").hookAfterAllMethods(
16 | "bind"
17 | ) {
18 | val mContent = XposedHelpers.getObjectField(it.thisObject, "mContent") as GridView
19 | mContent.verticalSpacing = dp2px(verticalPadding.toFloat())
20 | }
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/HapticFeedback.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.yuk.miuiHomeR.mPrefsMap
5 | import com.yuk.miuiHomeR.utils.ktx.callMethod
6 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
7 | import com.yuk.miuiHomeR.utils.ktx.replaceMethod
8 |
9 | object HapticFeedback : BaseHook() {
10 | override fun init() {
11 |
12 | if (!mPrefsMap.getBoolean("haptic_feedback")) return
13 | val value = mPrefsMap.getInt("haptic_Back_HandUp", 2)
14 | val value1 = mPrefsMap.getInt("haptic_Back_ReadyBack", 2)
15 | findMethod("com.miui.home.launcher.common.HapticFeedbackCompatLinear") {
16 | name == "lambda\$performGestureBackHandUp\$8" && parameterCount == 1
17 | }.replaceMethod {
18 | it.args[0].getObjectField("mHapticHelper")?.callMethod("performExtHapticFeedback", value)
19 | }
20 |
21 | findMethod("com.miui.home.launcher.common.HapticFeedbackCompatLinear") {
22 | name == "lambda\$performGestureReadyBack\$7" && parameterCount == 1
23 | }.replaceMethod {
24 | it.args[0].getObjectField("mHapticHelper")?.callMethod("performExtHapticFeedback", value1)
25 | }
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/HideSeekPoint.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.view.View
4 | import android.view.ViewGroup
5 | import com.yuk.miuiHomeR.mPrefsMap
6 | import com.yuk.miuiHomeR.utils.ktx.callMethod
7 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
8 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
9 |
10 | object HideSeekPoint : BaseHook() {
11 | override fun init() {
12 |
13 | if (!mPrefsMap.getBoolean("home_hide_seek_point")) return
14 | "com.miui.home.launcher.ScreenView".hookAfterMethod(
15 | "updateSeekPoints", Int::class.javaPrimitiveType
16 | ) {
17 | showSeekBar(it.thisObject as View)
18 | }
19 | "com.miui.home.launcher.ScreenView".hookAfterMethod(
20 | "addView", View::class.java, Int::class.javaPrimitiveType, ViewGroup.LayoutParams::class.java
21 | ) {
22 | showSeekBar(it.thisObject as View)
23 | }
24 | "com.miui.home.launcher.ScreenView".hookAfterMethod(
25 | "removeScreen", Int::class.javaPrimitiveType
26 | ) {
27 | showSeekBar(it.thisObject as View)
28 | }
29 | "com.miui.home.launcher.ScreenView".hookAfterMethod(
30 | "removeScreensInLayout", Int::class.javaPrimitiveType, Int::class.javaPrimitiveType
31 | ) {
32 | showSeekBar(it.thisObject as View)
33 | }
34 | }
35 |
36 | private fun showSeekBar(view: View) {
37 | if ("Workspace" != view.javaClass.simpleName) return
38 | val mScreenSeekBar = view.getObjectField("mScreenSeekBar") as View
39 | val isInEditingMode = view.callMethod("isInNormalEditingMode") as Boolean
40 | if (!isInEditingMode) {
41 | mScreenSeekBar.animate().cancel()
42 | mScreenSeekBar.visibility = View.GONE
43 | }
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/HideStatusBarWhenEnterRecent.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
5 | import com.yuk.miuiHomeR.mPrefsMap
6 |
7 | object HideStatusBarWhenEnterRecent : BaseHook() {
8 | override fun init() {
9 |
10 | if (mPrefsMap.getBoolean("home_hide_status")) {
11 | findMethod("com.miui.home.launcher.common.DeviceLevelUtils") {
12 | name == "isHideStatusBarWhenEnterRecents"
13 | }.hookReturnConstant(true)
14 | findMethod("com.miui.home.launcher.DeviceConfig") {
15 | name == "keepStatusBarShowingForBetterPerformance"
16 | }.hookReturnConstant(false)
17 | } else {
18 | findMethod("com.miui.home.launcher.common.DeviceLevelUtils") {
19 | name == "isHideStatusBarWhenEnterRecents"
20 | }.hookReturnConstant(false)
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/HideWidgetTitles.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.view.View
4 | import com.github.kyuubiran.ezxhelper.utils.findMethod
5 | import com.github.kyuubiran.ezxhelper.utils.hookAfter
6 | import com.github.kyuubiran.ezxhelper.utils.invokeMethodAuto
7 | import com.github.kyuubiran.ezxhelper.utils.loadClass
8 | import com.yuk.miuiHomeR.mPrefsMap
9 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
10 | import java.util.function.Predicate
11 |
12 | object HideWidgetTitles : BaseHook() {
13 | override fun init() {
14 |
15 | if (!mPrefsMap.getBoolean("home_widget_hide")) return
16 | val maMlWidgetInfo = loadClass("com.miui.home.launcher.maml.MaMlWidgetInfo")
17 | findMethod("com.miui.home.launcher.LauncherAppWidgetHost") {
18 | name == "createLauncherWidgetView" && parameterCount == 4
19 | }.hookAfter {
20 | val view = it.result as Any
21 | view.invokeMethodAuto("getTitleView")?.invokeMethodAuto("setVisibility", View.GONE)
22 | }
23 | "com.miui.home.launcher.Launcher".hookAfterMethod(
24 | "addMaMl", maMlWidgetInfo, Boolean::class.java, Predicate::class.java
25 | ) {
26 | val view = it.result as Any
27 | view.invokeMethodAuto("getTitleView")?.invokeMethodAuto("setVisibility", View.GONE)
28 | }
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/HomeSettings.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.content.ComponentName
4 | import android.content.Intent
5 | import android.view.View
6 | import com.github.kyuubiran.ezxhelper.init.InitFields.appContext
7 | import com.github.kyuubiran.ezxhelper.init.InitFields.moduleRes
8 | import com.yuk.miuiHomeR.R
9 | import com.yuk.miuiHomeR.utils.ktx.callMethod
10 | import com.yuk.miuiHomeR.utils.ktx.findClass
11 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
12 | import com.yuk.miuiHomeR.utils.ktx.hookAfterAllMethods
13 | import com.yuk.miuiHomeR.utils.ktx.setObjectField
14 | import de.robv.android.xposed.XposedHelpers
15 |
16 | object HomeSettings : BaseHook() {
17 | override fun init() {
18 |
19 | "com.miui.home.settings.MiuiHomeSettings".findClass().hookAfterAllMethods("onCreatePreferences") {
20 | val mLayoutResId = (it.thisObject.getObjectField("mAllAppsSetting"))?.getObjectField("mLayoutResId")
21 | val mWidgetLayoutResId = (it.thisObject.getObjectField("mAllAppsSetting"))?.getObjectField("mWidgetLayoutResId")
22 | val pref = XposedHelpers.newInstance("com.miui.home.settings.preference.ValuePreference".findClass(), appContext).apply {
23 | setObjectField("mTitle", "MiuiHomeR")
24 | setObjectField("mOrder", 0)
25 | setObjectField("mVisible", true)
26 | setObjectField("mLayoutResId", mLayoutResId)
27 | setObjectField("mWidgetLayoutResId", mWidgetLayoutResId)
28 | setObjectField("mFragment", "MiuiHomeR")
29 | callMethod("setValue", moduleRes.getString(R.string.module_settings))
30 | setObjectField("mClickListener", object : View.OnClickListener {
31 | override fun onClick(v: View) {
32 | val intent = Intent()
33 | intent.component = ComponentName("com.yuk.miuiHomeR", "com.yuk.miuiHomeR.ui.MainActivity")
34 | intent.putExtra("homeAsUpEnabled", true)
35 | v.context.startActivity(intent)
36 | }
37 | })
38 | callMethod("setIntent", Intent())
39 | }
40 | it.thisObject.callMethod("getPreferenceScreen")?.callMethod("addPreference", pref)
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/IconTitleColor.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import com.github.kyuubiran.ezxhelper.utils.Log
9 | import com.yuk.miuiHomeR.mPrefsMap
10 | import com.yuk.miuiHomeR.utils.ktx.callMethod
11 | import com.yuk.miuiHomeR.utils.ktx.findClass
12 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
13 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
14 |
15 | object IconTitleColor : BaseHook() {
16 | @SuppressLint("DiscouragedApi")
17 | override fun init() {
18 |
19 | val value = mPrefsMap.getInt("icon_title_font_color", -1)
20 | val launcherClass = "com.miui.home.launcher.Launcher".findClass()
21 | val shortcutInfoClass = "com.miui.home.launcher.ShortcutInfo".findClass()
22 | if (value == -1) return
23 | try {
24 | "com.miui.home.launcher.ItemIcon".hookAfterMethod(
25 | "onFinishInflate"
26 | ) {
27 | val mTitle = it.thisObject.getObjectField("mTitle") as TextView
28 | mTitle.setTextColor(value)
29 | }
30 | "com.miui.home.launcher.maml.MaMlWidgetView".hookAfterMethod(
31 | "onFinishInflate"
32 | ) {
33 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
34 | mTitle.setTextColor(value)
35 | }
36 | "com.miui.home.launcher.LauncherMtzGadgetView".hookAfterMethod(
37 | "onFinishInflate"
38 | ) {
39 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
40 | mTitle.setTextColor(value)
41 | }
42 | "com.miui.home.launcher.LauncherWidgetView".hookAfterMethod(
43 | "onFinishInflate"
44 | ) {
45 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
46 | mTitle.setTextColor(value)
47 | }
48 | "com.miui.home.launcher.ShortcutIcon".hookAfterMethod(
49 | "fromXml", Int::class.javaPrimitiveType, launcherClass, ViewGroup::class.java, shortcutInfoClass
50 | ) {
51 | val buddyIconView = it.args[3].callMethod("getBuddyIconView", it.args[2]) as View
52 | val mTitle = buddyIconView.getObjectField("mTitle") as TextView
53 | mTitle.setTextColor(value)
54 | }
55 | "com.miui.home.launcher.ShortcutIcon".hookAfterMethod(
56 | "createShortcutIcon", Int::class.javaPrimitiveType, launcherClass, ViewGroup::class.java
57 | ) {
58 | val buddyIcon = it.result as View
59 | val mTitle = buddyIcon.getObjectField("mTitle") as TextView
60 | mTitle.setTextColor(value)
61 | }
62 | "com.miui.home.launcher.common.Utilities".hookAfterMethod(
63 | "adaptTitleStyleToWallpaper", Context::class.java, TextView::class.java, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType
64 | ) {
65 | val mTitle = it.args[1] as TextView
66 | if (mTitle.id == mTitle.resources.getIdentifier("icon_title", "id", "com.miui.home")) {
67 | mTitle.setTextColor(value)
68 | }
69 | }
70 | } catch (e: Throwable) {
71 | Log.ex(e)
72 | }
73 |
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/IconTitleScrolling.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.text.TextUtils
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.TextView
9 | import com.github.kyuubiran.ezxhelper.utils.Log
10 | import com.yuk.miuiHomeR.mPrefsMap
11 | import com.yuk.miuiHomeR.utils.ktx.callMethod
12 | import com.yuk.miuiHomeR.utils.ktx.findClass
13 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
14 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
15 |
16 | object IconTitleScrolling : BaseHook() {
17 | @SuppressLint("DiscouragedApi")
18 | override fun init() {
19 |
20 | if (!mPrefsMap.getBoolean("icon_title_font_scrolling")) return
21 | val launcherClass = "com.miui.home.launcher.Launcher".findClass()
22 | val shortcutInfoClass = "com.miui.home.launcher.ShortcutInfo".findClass()
23 | try {
24 | "com.miui.home.launcher.ItemIcon".hookAfterMethod(
25 | "onFinishInflate"
26 | ) {
27 | val mTitle = it.thisObject.getObjectField("mTitle") as TextView
28 | mTitleScrolling(mTitle)
29 | }
30 | "com.miui.home.launcher.maml.MaMlWidgetView".hookAfterMethod(
31 | "onFinishInflate"
32 | ) {
33 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
34 | mTitleScrolling(mTitle)
35 | }
36 | "com.miui.home.launcher.LauncherMtzGadgetView".hookAfterMethod(
37 | "onFinishInflate"
38 | ) {
39 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
40 | mTitleScrolling(mTitle)
41 | }
42 | "com.miui.home.launcher.LauncherWidgetView".hookAfterMethod(
43 | "onFinishInflate"
44 | ) {
45 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
46 | mTitleScrolling(mTitle)
47 | }
48 | "com.miui.home.launcher.ShortcutIcon".hookAfterMethod(
49 | "fromXml", Int::class.javaPrimitiveType, launcherClass, ViewGroup::class.java, shortcutInfoClass
50 | ) {
51 | val buddyIconView = it.args[3].callMethod("getBuddyIconView", it.args[2]) as View
52 | val mTitle = buddyIconView.getObjectField("mTitle") as TextView
53 | mTitleScrolling(mTitle)
54 | }
55 | "com.miui.home.launcher.ShortcutIcon".hookAfterMethod(
56 | "createShortcutIcon", Int::class.javaPrimitiveType, launcherClass, ViewGroup::class.java
57 | ) {
58 | val buddyIcon = it.result as View
59 | val mTitle = buddyIcon.getObjectField("mTitle") as TextView
60 | mTitleScrolling(mTitle)
61 | }
62 | "com.miui.home.launcher.common.Utilities".hookAfterMethod(
63 | "adaptTitleStyleToWallpaper", Context::class.java, TextView::class.java, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType
64 | ) {
65 | val mTitle = it.args[1] as TextView
66 | if (mTitle.id == mTitle.resources.getIdentifier("icon_title", "id", "com.miui.home")) {
67 | mTitleScrolling(mTitle)
68 | }
69 | }
70 | } catch (e: Throwable) {
71 | Log.ex(e)
72 | }
73 |
74 | }
75 |
76 | private fun mTitleScrolling(mTitle: TextView) {
77 | mTitle.ellipsize = TextUtils.TruncateAt.MARQUEE
78 | mTitle.isHorizontalFadingEdgeEnabled = true
79 | mTitle.setSingleLine()
80 | mTitle.marqueeRepeatLimit = -1
81 | mTitle.isSelected = true
82 | mTitle.setHorizontallyScrolling(true)
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/IconTitleSize.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.util.TypedValue
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.TextView
9 | import com.github.kyuubiran.ezxhelper.utils.Log
10 | import com.yuk.miuiHomeR.mPrefsMap
11 | import com.yuk.miuiHomeR.utils.ktx.callMethod
12 | import com.yuk.miuiHomeR.utils.ktx.findClass
13 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
14 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
15 |
16 | object IconTitleSize : BaseHook() {
17 | @SuppressLint("DiscouragedApi")
18 | override fun init() {
19 |
20 | val value = mPrefsMap.getInt("icon_title_font_size", -1).toFloat()
21 | val launcherClass = "com.miui.home.launcher.Launcher".findClass()
22 | val shortcutInfoClass = "com.miui.home.launcher.ShortcutInfo".findClass()
23 | if (value == -1f) return
24 | try {
25 | "com.miui.home.launcher.ItemIcon".hookAfterMethod(
26 | "onFinishInflate"
27 | ) {
28 | val mTitle = it.thisObject.getObjectField("mTitle") as TextView
29 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
30 | }
31 | "com.miui.home.launcher.maml.MaMlWidgetView".hookAfterMethod(
32 | "onFinishInflate"
33 | ) {
34 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
35 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
36 | }
37 | "com.miui.home.launcher.LauncherMtzGadgetView".hookAfterMethod(
38 | "onFinishInflate"
39 | ) {
40 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
41 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
42 | }
43 | "com.miui.home.launcher.LauncherWidgetView".hookAfterMethod(
44 | "onFinishInflate"
45 | ) {
46 | val mTitle = it.thisObject.getObjectField("mTitleTextView") as TextView
47 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
48 | }
49 | "com.miui.home.launcher.ShortcutIcon".hookAfterMethod(
50 | "fromXml", Int::class.javaPrimitiveType, launcherClass, ViewGroup::class.java, shortcutInfoClass
51 | ) {
52 | val buddyIconView = it.args[3].callMethod("getBuddyIconView", it.args[2]) as View
53 | val mTitle = buddyIconView.getObjectField("mTitle") as TextView
54 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
55 | }
56 | "com.miui.home.launcher.ShortcutIcon".hookAfterMethod(
57 | "createShortcutIcon", Int::class.javaPrimitiveType, launcherClass, ViewGroup::class.java
58 | ) {
59 | val buddyIcon = it.result as View
60 | val mTitle = buddyIcon.getObjectField("mTitle") as TextView
61 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
62 | }
63 | "com.miui.home.launcher.common.Utilities".hookAfterMethod(
64 | "adaptTitleStyleToWallpaper", Context::class.java, TextView::class.java, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType
65 | ) {
66 | val mTitle = it.args[1] as TextView
67 | if (mTitle.id == mTitle.resources.getIdentifier("icon_title", "id", "com.miui.home")) {
68 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, value)
69 | }
70 | }
71 | } catch (e: Throwable) {
72 | Log.ex(e)
73 | }
74 |
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/InfiniteScroll.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.yuk.miuiHomeR.mPrefsMap
4 | import com.yuk.miuiHomeR.utils.ktx.callMethod
5 | import com.yuk.miuiHomeR.utils.ktx.getIntField
6 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
7 |
8 | object InfiniteScroll : BaseHook() {
9 | override fun init() {
10 |
11 | if (!mPrefsMap.getBoolean("home_infinite_scroll")) return
12 | "com.miui.home.launcher.ScreenView".hookAfterMethod(
13 | "getSnapToScreenIndex", Int::class.javaPrimitiveType, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType
14 | ) {
15 | if (it.args[0] !== it.result) return@hookAfterMethod
16 | val screenCount = it.thisObject.callMethod("getScreenCount") as Int
17 | if (it.args[2] as Int == -1 && it.args[0] as Int == 0) it.result = screenCount
18 | else if (it.args[2] as Int == 1 && it.args[0] as Int == screenCount - 1) it.result = 0
19 | }
20 | "com.miui.home.launcher.ScreenView".hookAfterMethod(
21 | "getSnapUnitIndex", Int::class.javaPrimitiveType
22 | ) {
23 | val mCurrentScreenIndex = it.thisObject.getIntField("mCurrentScreenIndex")
24 | if (mCurrentScreenIndex != it.result as Int) return@hookAfterMethod
25 | val screenCount = it.thisObject.callMethod("getScreenCount") as Int
26 | if (it.result as Int == 0) it.result = screenCount
27 | else if (it.result as Int == screenCount - 1) it.result = 0
28 | }
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/OverlapMode.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
5 | import com.yuk.miuiHomeR.mPrefsMap
6 |
7 | object OverlapMode : BaseHook() {
8 | override fun init() {
9 |
10 | if (!mPrefsMap.getBoolean("home_overlap_mode")) return
11 | findMethod("com.miui.home.launcher.overlay.assistant.AssistantDeviceAdapter") {
12 | name == "inOverlapMode"
13 | }.hookReturnConstant(true)
14 |
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/Recent.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.util.TypedValue
4 | import android.view.View
5 | import android.widget.ImageView
6 | import android.widget.TextView
7 | import com.yuk.miuiHomeR.mPrefsMap
8 | import com.yuk.miuiHomeR.utils.ktx.findClass
9 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
10 | import com.yuk.miuiHomeR.utils.ktx.hookAfterAllConstructors
11 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
12 | import com.yuk.miuiHomeR.utils.ktx.setIntField
13 |
14 | object Recent : BaseHook() {
15 | override fun init() {
16 |
17 | val recentsContainerClass = "com.miui.home.recents.views.RecentsContainer".findClass()
18 | if (mPrefsMap.getBoolean("home_hide_small_window")) {
19 | recentsContainerClass.hookAfterMethod(
20 | "onFinishInflate"
21 | ) {
22 | val mTitle = it.thisObject.getObjectField("mTxtSmallWindow") as TextView
23 | mTitle.visibility = View.GONE
24 | }
25 | }
26 |
27 | if (mPrefsMap.getBoolean("home_hide_clean_up")) {
28 | recentsContainerClass.hookAfterMethod(
29 | "onFinishInflate"
30 | ) {
31 | val mView = it.thisObject.getObjectField("mClearAnimView") as View
32 | mView.visibility = View.GONE
33 | }
34 | }
35 |
36 | val appCardBgColor = mPrefsMap.getInt("recents_card_bg_color", -1)
37 | if (appCardBgColor != -1) {
38 | "com.miui.home.recents.views.TaskViewThumbnail".findClass().hookAfterAllConstructors {
39 | it.thisObject.setIntField("mBgColorForSmallWindow", appCardBgColor)
40 | }
41 | }
42 |
43 | val recentTextSize = mPrefsMap.getInt("recents_text_size", -1)
44 | if (recentTextSize != -1) {
45 | val taskViewHeaderClass = "com.miui.home.recents.views.TaskViewHeader".findClass()
46 | taskViewHeaderClass.hookAfterMethod(
47 | "onFinishInflate"
48 | ) {
49 | val mTitle = it.thisObject.getObjectField("mTitleView") as TextView
50 | mTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, recentTextSize.toFloat())
51 | if (recentTextSize == 0) mTitle.visibility = View.GONE
52 | }
53 | }
54 |
55 | val recentTextColor = mPrefsMap.getInt("recents_text_color", -1)
56 | if (recentTextSize != -1) {
57 | val taskViewHeaderClass = "com.miui.home.recents.views.TaskViewHeader".findClass()
58 | taskViewHeaderClass.hookAfterMethod(
59 | "onFinishInflate"
60 | ) {
61 | val mTitle = it.thisObject.getObjectField("mTitleView") as TextView
62 | mTitle.setTextColor(recentTextColor)
63 | }
64 | }
65 |
66 | val emptyViewText = mPrefsMap.getString("recent_text", "")
67 | if (emptyViewText != "") {
68 | "com.miui.home.recents.views.RecentsView".hookAfterMethod(
69 | "showEmptyView", Int::class.javaPrimitiveType
70 | ) {
71 | (it.thisObject.getObjectField("mEmptyView") as TextView).apply {
72 | this.text = emptyViewText
73 | }
74 | }
75 | }
76 |
77 | if (mPrefsMap.getBoolean("recents_icon")) {
78 | "com.miui.home.recents.views.TaskViewHeader".hookAfterMethod(
79 | "onFinishInflate"
80 | ) {
81 | val mImage = it.thisObject.getObjectField("mIconView") as ImageView
82 | mImage.visibility = View.GONE
83 | }
84 | }
85 |
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/RemoveCardAnim.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.animation.ObjectAnimator
4 | import android.view.MotionEvent
5 | import android.view.View
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ktx.callMethod
8 | import com.yuk.miuiHomeR.utils.ktx.callStaticMethod
9 | import com.yuk.miuiHomeR.utils.ktx.findClass
10 | import com.yuk.miuiHomeR.utils.ktx.getObjectField
11 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
12 | import com.yuk.miuiHomeR.utils.ktx.replaceMethod
13 | import com.yuk.miuiHomeR.utils.ktx.setObjectField
14 |
15 | object RemoveCardAnim : BaseHook() {
16 | override fun init() {
17 |
18 | if (!mPrefsMap.getBoolean("recents_card_remove_anim")) return
19 | "com.miui.home.recents.views.SwipeHelperForRecents".hookAfterMethod("onTouchEvent", MotionEvent::class.java) {
20 | if (it.thisObject.getObjectField("mCurrView") != null) {
21 | val taskView2 = it.thisObject.getObjectField("mCurrView") as View
22 | taskView2.alpha = 1f
23 | taskView2.scaleX = 1f
24 | taskView2.scaleY = 1f
25 | }
26 | }
27 | "com.miui.home.recents.TaskStackViewLayoutStyleHorizontal".replaceMethod(
28 | "createScaleDismissAnimation", View::class.java, Float::class.java
29 | ) {
30 | val view = it.args[0] as View
31 | val getScreenHeight = "com.miui.home.launcher.DeviceConfig".findClass().callStaticMethod("getScreenHeight") as Int
32 | val ofFloat = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, view.translationY, -getScreenHeight * 1.1484375f)
33 | ofFloat.duration = 200
34 | return@replaceMethod ofFloat
35 | }
36 |
37 | "com.miui.home.recents.views.VerticalSwipe".hookAfterMethod("calculate", Float::class.java) {
38 | val f = it.args[0] as Float
39 | val asScreenHeightWhenDismiss =
40 | "com.miui.home.recents.views.VerticalSwipe".findClass().callStaticMethod("getAsScreenHeightWhenDismiss") as Int
41 | val f2 = f / asScreenHeightWhenDismiss
42 | val mTaskViewHeight = it.thisObject.getObjectField("mTaskViewHeight") as Float
43 | val mCurScale = it.thisObject.getObjectField("mCurScale") as Float
44 | val f3: Float = mTaskViewHeight * mCurScale
45 | val i = if (f2 > 0.0f) 1 else if (f2 == 0.0f) 0 else -1
46 | val afterFrictionValue: Float = it.thisObject.callMethod("afterFrictionValue", f, asScreenHeightWhenDismiss) as Float
47 | if (i < 0) it.thisObject.setObjectField("mCurTransY", (mTaskViewHeight / 2.0f + afterFrictionValue * 2) - (f3 / 2.0f))
48 | }
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/ResourcesHook.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.content.res.Resources
4 | import com.github.kyuubiran.ezxhelper.init.InitFields.appContext
5 | import com.github.kyuubiran.ezxhelper.utils.Log
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ResourcesHookData
8 | import com.yuk.miuiHomeR.utils.ResourcesHookMap
9 | import com.yuk.miuiHomeR.utils.ktx.dp2px
10 | import com.yuk.miuiHomeR.utils.ktx.findClass
11 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeAllMethods
12 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
13 | import de.robv.android.xposed.XC_MethodHook
14 |
15 | object ResourcesHook : BaseHook() {
16 | private val hookMap = ResourcesHookMap()
17 | private fun hook(param: XC_MethodHook.MethodHookParam) {
18 | try {
19 | val resName = appContext.resources.getResourceEntryName(param.args[0] as Int)
20 | val resType = appContext.resources.getResourceTypeName(param.args[0] as Int)
21 | if (hookMap.isKeyExist(resName)) if (hookMap[resName]?.type == resType) {
22 | param.result = hookMap[resName]?.afterValue
23 | }
24 | } catch (ignore: Exception) {
25 | }
26 | }
27 |
28 | override fun init() {
29 |
30 | Resources::class.java.hookBeforeMethod("getBoolean", Int::class.javaPrimitiveType) { hook(it) }
31 | Resources::class.java.hookBeforeMethod("getDimension", Int::class.javaPrimitiveType) { hook(it) }
32 | Resources::class.java.hookBeforeMethod("getDimensionPixelOffset", Int::class.javaPrimitiveType) { hook(it) }
33 | Resources::class.java.hookBeforeMethod("getDimensionPixelSize", Int::class.javaPrimitiveType) { hook(it) }
34 | Resources::class.java.hookBeforeMethod("getInteger", Int::class.javaPrimitiveType) { hook(it) }
35 | Resources::class.java.hookBeforeMethod("getText", Int::class.javaPrimitiveType) { hook(it) }
36 |
37 | val value = mPrefsMap.getInt("task_view_corners", -1).toFloat()
38 | val value1 = mPrefsMap.getInt("task_view_header_height", -1).toFloat()
39 | if (mPrefsMap.getBoolean("home_unlock_grids")) {
40 | val deviceClass = "com.miui.home.launcher.compat.LauncherCellCountCompatDevice".findClass()
41 | deviceClass.hookBeforeAllMethods("shouldUseDeviceValue") { it.result = false }
42 | hookMap["config_cell_count_x"] = ResourcesHookData("integer", 3)
43 | hookMap["config_cell_count_y"] = ResourcesHookData("integer", 4)
44 | hookMap["config_cell_count_x_min"] = ResourcesHookData("integer", 3)
45 | hookMap["config_cell_count_y_min"] = ResourcesHookData("integer", 4)
46 | hookMap["config_cell_count_x_max"] = ResourcesHookData("integer", 16)
47 | hookMap["config_cell_count_y_max"] = ResourcesHookData("integer", 18)
48 | try {
49 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod("isThemeCoverCellConfig") {
50 | it.result = true
51 | }
52 | } catch (e: Throwable) {
53 | Log.ex(e)
54 | }
55 | }
56 | if (value != -1f && value != 20f) {
57 | hookMap["recents_task_view_rounded_corners_radius_min"] = ResourcesHookData("dimen", dp2px(value))
58 | hookMap["recents_task_view_rounded_corners_radius_max"] = ResourcesHookData("dimen", dp2px(value))
59 | }
60 | if (value1 != -1f && value != 40f) hookMap["recents_task_view_header_height"] = ResourcesHookData("dimen", dp2px(value1))
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/SetDeviceLevel.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.Log
4 | import com.github.kyuubiran.ezxhelper.utils.findMethod
5 | import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
6 | import com.yuk.miuiHomeR.utils.ktx.checkVersionCode
7 | import com.yuk.miuiHomeR.utils.ktx.findClass
8 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
9 | import com.yuk.miuiHomeR.utils.ktx.replaceMethod
10 |
11 | object SetDeviceLevel : BaseHook() {
12 | override fun init() {
13 |
14 | try {
15 | findMethod("com.miui.home.launcher.common.CpuLevelUtils") {
16 | name == "getQualcommCpuLevel" && parameterCount == 1
17 | }
18 | } catch (e: Exception) {
19 | findMethod("miuix.animation.utils.DeviceUtils") {
20 | name == "getQualcommCpuLevel" && parameterCount == 1
21 | }
22 | }.hookReturnConstant(2)
23 | try {
24 | "com.miui.home.launcher.common.DeviceLevelUtils".hookBeforeMethod("getDeviceLevel") {
25 | it.result = 2
26 | }
27 | } catch (e: Throwable) {
28 | Log.ex(e)
29 | }
30 | try {
31 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod("isSupportCompleteAnimation") {
32 | it.result = true
33 | }
34 | } catch (e: Throwable) {
35 | Log.ex(e)
36 | }
37 | try {
38 | "com.miui.home.launcher.common.DeviceLevelUtils".hookBeforeMethod("isLowLevelOrLiteDevice") {
39 | it.result = false
40 | }
41 | } catch (e: Throwable) {
42 | Log.ex(e)
43 | }
44 | try {
45 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod("isMiuiLiteVersion") {
46 | it.result = false
47 | }
48 | } catch (e: Throwable) {
49 | Log.ex(e)
50 | }
51 | try {
52 | "com.miui.home.launcher.util.noword.NoWordSettingHelperKt".hookBeforeMethod("isNoWordAvailable") {
53 | it.result = true
54 | }
55 | } catch (e: Throwable) {
56 | Log.ex(e)
57 | }
58 | try {
59 | "android.os.SystemProperties".hookBeforeMethod(
60 | "getBoolean", String::class.java, Boolean::class.java
61 | ) {
62 | if (it.args[0] == "ro.config.low_ram.threshold_gb") it.result = false
63 | }
64 | } catch (e: Throwable) {
65 | Log.ex(e)
66 | }
67 | try {
68 | "android.os.SystemProperties".hookBeforeMethod(
69 | "getBoolean", String::class.java, Boolean::class.java
70 | ) {
71 | if (it.args[0] == "ro.miui.backdrop_sampling_enabled") it.result = true
72 | }
73 | } catch (e: Throwable) {
74 | Log.ex(e)
75 | }
76 | try {
77 | "com.miui.home.launcher.common.Utilities".hookBeforeMethod("canLockTaskView") {
78 | it.result = true
79 | }
80 | } catch (e: Throwable) {
81 | Log.ex(e)
82 | }
83 | try {
84 | "com.miui.home.launcher.MIUIWidgetUtil".hookBeforeMethod("isMIUIWidgetSupport") {
85 | it.result = true
86 | }
87 | } catch (e: Throwable) {
88 | Log.ex(e)
89 | }
90 | try {
91 | if (checkVersionCode() <= 426004312L) "com.miui.home.launcher.MiuiHomeLog".hookBeforeMethod(
92 | "setDebugLogState", Boolean::class.java
93 | ) {
94 | it.result = false
95 | }
96 | } catch (e: Throwable) {
97 | Log.ex(e)
98 | }
99 | try {
100 | "com.miui.home.launcher.MiuiHomeLog".findClass().replaceMethod(
101 | "log", String::class.java, String::class.java
102 | ) {
103 | return@replaceMethod null
104 | }
105 | } catch (e: Throwable) {
106 | Log.ex(e)
107 | }
108 | try {
109 | "com.xiaomi.onetrack.OneTrack".hookBeforeMethod("isDisable") {
110 | it.result = true
111 | }
112 | } catch (e: Throwable) {
113 | Log.ex(e)
114 | }
115 |
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/ShortcutItemCount.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 |
4 | import com.github.kyuubiran.ezxhelper.utils.findMethod
5 | import com.github.kyuubiran.ezxhelper.utils.hookAfter
6 | import com.yuk.miuiHomeR.mPrefsMap
7 | import com.yuk.miuiHomeR.utils.ktx.callMethod
8 |
9 | object ShortcutItemCount : BaseHook() {
10 | override fun init() {
11 |
12 | if (!mPrefsMap.getBoolean("shortcut_remove_restrictions")) return
13 | findMethod("com.miui.home.launcher.shortcuts.AppShortcutMenu") { name == "getMaxCountInCurrentOrientation" }.hookAfter {
14 | it.result = 20
15 | }
16 | findMethod("com.miui.home.launcher.shortcuts.AppShortcutMenu") { name == "getMaxShortcutItemCount" }.hookAfter {
17 | it.result = 20
18 | }
19 | findMethod("com.miui.home.launcher.shortcuts.AppShortcutMenu") { name == "getMaxVisualHeight" }.hookAfter {
20 | it.result = it.thisObject.callMethod("getItemHeight")
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/ShortcutSmallWindow.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.ComponentName
5 | import android.content.Intent
6 | import android.os.Bundle
7 | import android.view.View
8 | import com.github.kyuubiran.ezxhelper.init.InitFields.moduleRes
9 | import com.yuk.miuiHomeR.R
10 | import com.yuk.miuiHomeR.mPrefsMap
11 | import com.yuk.miuiHomeR.utils.ktx.callMethod
12 | import com.yuk.miuiHomeR.utils.ktx.callStaticMethod
13 | import com.yuk.miuiHomeR.utils.ktx.findClass
14 | import com.yuk.miuiHomeR.utils.ktx.getStaticObjectField
15 | import com.yuk.miuiHomeR.utils.ktx.hookAfterAllMethods
16 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
17 | import com.yuk.miuiHomeR.utils.ktx.isDarkMode
18 | import com.yuk.miuiHomeR.utils.ktx.setStaticObjectField
19 | import de.robv.android.xposed.XposedBridge
20 | import de.robv.android.xposed.XposedHelpers
21 |
22 | @SuppressLint("StaticFieldLeak", "DiscouragedApi")
23 | object ShortcutSmallWindow : BaseHook() {
24 | @SuppressLint("UseCompatLoadingForDrawables")
25 | override fun init() {
26 |
27 | if (!mPrefsMap.getBoolean("shortcut_small_window")) return
28 | val mViewDarkModeHelper = ("com.miui.home.launcher.util.ViewDarkModeHelper").findClass()
29 | val mSystemShortcutMenu = ("com.miui.home.launcher.shortcuts.SystemShortcutMenu").findClass()
30 | val mSystemShortcutMenuItem = ("com.miui.home.launcher.shortcuts.SystemShortcutMenuItem").findClass()
31 | val mAppShortcutMenu = ("com.miui.home.launcher.shortcuts.AppShortcutMenu").findClass()
32 | val mShortcutMenuItem = ("com.miui.home.launcher.shortcuts.ShortcutMenuItem").findClass()
33 | val mAppDetailsShortcutMenuItem = ("com.miui.home.launcher.shortcuts.SystemShortcutMenuItem\$AppDetailsShortcutMenuItem").findClass()
34 | val mActivityUtilsCompat = ("com.miui.launcher.utils.ActivityUtilsCompat").findClass()
35 | mViewDarkModeHelper.hookAfterAllMethods("onConfigurationChanged") {
36 | mSystemShortcutMenuItem.callStaticMethod("createAllSystemShortcutMenuItems")
37 | }
38 | mShortcutMenuItem.hookAfterAllMethods("getShortTitle") {
39 | if (it.result == "应用信息") {
40 | it.result = "信息"
41 | }
42 | }
43 | mAppDetailsShortcutMenuItem.hookBeforeMethod("lambda\$getOnClickListener$0", mAppDetailsShortcutMenuItem, View::class.java) {
44 | val obj = it.args[0]
45 | val view: View = it.args[1] as View
46 | val mShortTitle = obj.callMethod("getShortTitle") as CharSequence
47 | if (mShortTitle == moduleRes.getString(R.string.small_window)) {
48 | it.result = null
49 | val intent = Intent()
50 | val mComponentName = obj.callMethod("getComponentName") as ComponentName
51 | intent.action = "android.intent.action.MAIN"
52 | intent.addCategory("android.intent.category.DEFAULT")
53 | intent.component = mComponentName
54 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
55 | val callStaticMethod = mActivityUtilsCompat.callStaticMethod("makeFreeformActivityOptions", view.context, mComponentName.packageName)
56 | if (callStaticMethod != null) {
57 | view.context.startActivity(intent, callStaticMethod.callMethod("toBundle") as Bundle)
58 | }
59 | }
60 | }
61 | mSystemShortcutMenu.hookAfterAllMethods("getMaxShortcutItemCount") {
62 | it.result = 5
63 | }
64 | mAppShortcutMenu.hookAfterAllMethods("getMaxShortcutItemCount") {
65 | it.result = 5
66 | }
67 | mSystemShortcutMenuItem.hookAfterAllMethods("createAllSystemShortcutMenuItems") {
68 | val mAllSystemShortcutMenuItems = mSystemShortcutMenuItem.getStaticObjectField("sAllSystemShortcutMenuItems") as Collection
69 | val mSmallWindowInstance = XposedHelpers.newInstance(mAppDetailsShortcutMenuItem)
70 | mSmallWindowInstance.callMethod("setShortTitle", moduleRes.getString(R.string.small_window))
71 | XposedBridge.log(isDarkMode().toString())
72 | mSmallWindowInstance.callMethod(
73 | "setIconDrawable",
74 | if (isDarkMode()) moduleRes.getDrawable(R.drawable.ic_task_small_window_dark) else moduleRes.getDrawable(R.drawable.ic_task_small_window_light)
75 | )
76 | val sAllSystemShortcutMenuItems = ArrayList()
77 | sAllSystemShortcutMenuItems.add(mSmallWindowInstance)
78 | sAllSystemShortcutMenuItems.addAll(mAllSystemShortcutMenuItems)
79 | mSystemShortcutMenuItem.setStaticObjectField("sAllSystemShortcutMenuItems", sAllSystemShortcutMenuItems)
80 | }
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/ShowDockIconTitle.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.yuk.miuiHomeR.mPrefsMap
4 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
5 |
6 | object ShowDockIconTitle : BaseHook() {
7 | override fun init() {
8 |
9 | if (!mPrefsMap.getBoolean("home_dock_icon_title")) return
10 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod("isHotseatsAppTitleHided") {
11 | it.result = false
12 | }
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/TaskViewHorizontal.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.graphics.RectF
4 | import com.yuk.miuiHomeR.mPrefsMap
5 | import com.yuk.miuiHomeR.utils.ktx.callMethod
6 | import com.yuk.miuiHomeR.utils.ktx.callStaticMethod
7 | import com.yuk.miuiHomeR.utils.ktx.findClass
8 | import com.yuk.miuiHomeR.utils.ktx.hookAfterMethod
9 |
10 | object TaskViewHorizontal : BaseHook() {
11 | override fun init() {
12 |
13 | val value1 = mPrefsMap.getInt("task_view_horizontal1", 100).toFloat() / 100
14 | val value2 = mPrefsMap.getInt("task_view_horizontal2", 100).toFloat() / 100
15 | if (value1 == 1f && value2 == 1f) return
16 | "com.miui.home.recents.views.TaskStackViewsAlgorithmHorizontal".hookAfterMethod(
17 | "scaleTaskView", RectF::class.java,
18 | ) {
19 | "com.miui.home.recents.util.Utilities".findClass().callStaticMethod(
20 | "scaleRectAboutCenter", it.args[0], if (it.thisObject.callMethod("isLandscapeVisually") as Boolean) value2 else value1
21 | )
22 | }
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/TaskViewVertical.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import android.graphics.RectF
4 | import com.github.kyuubiran.ezxhelper.init.InitFields.appContext
5 | import com.yuk.miuiHomeR.mPrefsMap
6 | import com.yuk.miuiHomeR.utils.ktx.callStaticMethod
7 | import com.yuk.miuiHomeR.utils.ktx.findClass
8 | import com.yuk.miuiHomeR.utils.ktx.replaceMethod
9 |
10 | object TaskViewVertical : BaseHook() {
11 | override fun init() {
12 |
13 | val value = mPrefsMap.getInt("task_view_vertical", 100).toFloat() / 100
14 | if (value == -1f || value == 1f) return
15 | "com.miui.home.recents.views.TaskStackViewsAlgorithmVertical".replaceMethod(
16 | "scaleTaskView", RectF::class.java
17 | ) {
18 | "com.miui.home.recents.util.Utilities".findClass().callStaticMethod(
19 | "scaleRectAboutCenter",
20 | it.args[0],
21 | value * "com.miui.home.recents.util.Utilities".findClass().callStaticMethod("getTaskViewScale", appContext) as Float
22 | )
23 | }
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/UnlockAnim.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.github.kyuubiran.ezxhelper.utils.findMethod
4 | import com.github.kyuubiran.ezxhelper.utils.hookBefore
5 | import com.yuk.miuiHomeR.mPrefsMap
6 |
7 | object UnlockAnim : BaseHook() {
8 | override fun init() {
9 |
10 | if (!mPrefsMap.getBoolean("home_unlock_anim")) return
11 | findMethod("com.miui.home.launcher.compat.UserPresentAnimationCompatV12Phone") {
12 | name == "getSpringAnimator" && parameterCount == 6
13 | }.hookBefore {
14 | it.args[4] = 0.5f
15 | it.args[5] = 0.5f
16 | }
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/hook/UnlockHotseatIcon.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.hook
2 |
3 | import com.yuk.miuiHomeR.mPrefsMap
4 | import com.yuk.miuiHomeR.utils.ktx.hookBeforeMethod
5 |
6 | object UnlockHotseatIcon : BaseHook() {
7 | override fun init() {
8 |
9 | if (!mPrefsMap.getBoolean("home_unlock_hotseat")) return
10 | "com.miui.home.launcher.DeviceConfig".hookBeforeMethod("getHotseatMaxCount") {
11 | it.result = 99
12 | }
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/provider/SharedPrefsProvider.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.provider
2 |
3 | import android.content.ContentProvider
4 | import android.content.ContentValues
5 | import android.content.SharedPreferences
6 | import android.content.UriMatcher
7 | import android.content.res.AssetFileDescriptor
8 | import android.database.Cursor
9 | import android.database.MatrixCursor
10 | import android.net.Uri
11 | import android.os.ParcelFileDescriptor
12 | import com.yuk.miuiHomeR.utils.Helpers
13 | import com.yuk.miuiHomeR.utils.PrefsUtils
14 | import java.io.File
15 | import java.io.FileNotFoundException
16 |
17 | class SharedPrefsProvider : ContentProvider() {
18 |
19 | private var prefs: SharedPreferences? = null
20 | override fun onCreate(): Boolean {
21 | return try {
22 | prefs = context?.let { PrefsUtils.getSharedPrefs(it, true) }
23 | true
24 | } catch (throwable: Throwable) {
25 | false
26 | }
27 | }
28 |
29 | override fun query(
30 | uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?
31 | ): Cursor? {
32 | val parts = uri.pathSegments
33 | val cursor = MatrixCursor(arrayOf("data"))
34 | when (uriMatcher.match(uri)) {
35 | 0 -> {
36 | cursor.newRow().add("data", prefs!!.getString(parts[1], ""))
37 | return cursor
38 | }
39 |
40 | 1 -> {
41 | cursor.newRow().add("data", prefs!!.getString(parts[1], parts[2]))
42 | return cursor
43 | }
44 |
45 | 2 -> {
46 | cursor.newRow().add("data", prefs!!.getInt(parts[1], parts[2].toInt()))
47 | return cursor
48 | }
49 |
50 | 3 -> {
51 | cursor.newRow().add("data", if (prefs!!.getBoolean(parts[1], parts[2].toInt() == 1)) 1 else 0)
52 | return cursor
53 | }
54 |
55 | 4 -> {
56 | val strings = prefs!!.getStringSet(parts[1], LinkedHashSet())
57 | for (str in strings!!) cursor.newRow().add("data", str)
58 | return cursor
59 | }
60 | }
61 | return null
62 | }
63 |
64 | @Throws(FileNotFoundException::class)
65 | override fun openAssetFile(uri: Uri, mode: String): AssetFileDescriptor? {
66 | if (context == null) return null
67 | val parts = uri.pathSegments
68 | if (uriMatcher.match(uri) == 5) {
69 | var filename: String? = null
70 | if ("0" == parts[1]) filename = "test0.png" else if ("1" == parts[1]) filename = "test1.mp3" else if ("2" == parts[1]) filename =
71 | "test2.mp4" else if ("3" == parts[1] || "5" == parts[1]) filename = "test3.txt" else if ("4" == parts[1]) filename = "test4.zip"
72 | var afd: AssetFileDescriptor? = null
73 | if (filename != null) try {
74 | afd = context!!.assets.openFd(filename)
75 | } catch (t: Throwable) {
76 | t.printStackTrace()
77 | }
78 | return afd
79 | } else if (uriMatcher.match(uri) == 6) {
80 | val context = Helpers.getProtectedContext(context!!)
81 | val file = File(context.filesDir.toString() + "/shortcuts/" + parts[1] + "_shortcut.png")
82 | return if (!file.exists()) null else AssetFileDescriptor(
83 | ParcelFileDescriptor.open(
84 | file, ParcelFileDescriptor.MODE_READ_ONLY
85 | ), 0, AssetFileDescriptor.UNKNOWN_LENGTH
86 | )
87 | }
88 | return null
89 | }
90 |
91 | override fun getType(uri: Uri): String? {
92 | return null
93 | }
94 |
95 | override fun insert(uri: Uri, values: ContentValues?): Uri? {
96 | return null
97 | }
98 |
99 | override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int {
100 | return 0
101 | }
102 |
103 | override fun update(
104 | uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array?
105 | ): Int {
106 | return 0
107 | }
108 |
109 | companion object {
110 | const val AUTHORITY = "com.yuk.miuiHomeR.provider.sharedprefs"
111 | private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
112 |
113 | init {
114 | uriMatcher.addURI(AUTHORITY, "string/*/", 0)
115 | uriMatcher.addURI(AUTHORITY, "string/*/*", 1)
116 | uriMatcher.addURI(AUTHORITY, "integer/*/*", 2)
117 | uriMatcher.addURI(AUTHORITY, "boolean/*/*", 3)
118 | uriMatcher.addURI(AUTHORITY, "stringset/*", 4)
119 | uriMatcher.addURI(AUTHORITY, "test/*", 5)
120 | uriMatcher.addURI(AUTHORITY, "shortcut_icon/*", 6)
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/AboutActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.net.Uri
6 | import android.os.Bundle
7 | import androidx.fragment.app.Fragment
8 | import com.yuk.miuiHomeR.BuildConfig
9 | import com.yuk.miuiHomeR.R
10 | import com.yuk.miuiHomeR.ui.base.SubFragment
11 | import com.yuk.miuiHomeR.utils.ktx.getLocale
12 | import com.yuk.miuiHomeR.utils.ktx.setLocale
13 | import moralnorm.appcompat.app.PickerDragActivity
14 | import moralnorm.internal.utils.ViewUtils
15 | import moralnorm.preference.Preference
16 |
17 | class AboutActivity : PickerDragActivity() {
18 |
19 | override fun onCreate(bundle: Bundle?) {
20 | setTheme(if (ViewUtils.isNightMode(this)) R.style.Theme_AppCompat_Translucent_NoActionBar_NoAnimation_Dark else R.style.Theme_AppCompat_Translucent_NoActionBar_NoAnimation)
21 | super.onCreate(bundle)
22 | setDragContentView(R.layout.activity_main)
23 | supportFragmentManager.beginTransaction().replace(R.id.fragment_container, initFragment()).commit()
24 | }
25 |
26 | fun initFragment(): Fragment {
27 | return AboutFragment()
28 | }
29 |
30 | override fun attachBaseContext(base: Context) {
31 | super.attachBaseContext(setLocale(base, getLocale(base)))
32 | }
33 |
34 | class AboutFragment : SubFragment() {
35 | override fun getContentResId(): Int {
36 | return R.xml.prefs_about
37 | }
38 |
39 | override fun initPrefs() {
40 | val mVersion = findPreference("prefs_key_about_version")
41 | val mQQGroup = findPreference("prefs_key_about_join_qq_group")
42 |
43 | mVersion.title = "v" + BuildConfig.VERSION_NAME + " - " + BuildConfig.BUILD_TYPE
44 |
45 | mQQGroup.onPreferenceClickListener = Preference.OnPreferenceClickListener {
46 | joinQQGroup("g405srEn4hafy8xSJg1_EFJjxceLvpd7")
47 | true
48 | }
49 | }
50 |
51 | /****************
52 | *
53 | * 调用 joinQQGroup() 即可发起手Q客户端申请加群
54 | * @param key 由官网生成的key
55 | * @return 返回true表示呼起手Q成功,返回false表示呼起失败
56 | */
57 | private fun joinQQGroup(key: String): Boolean {
58 | val intent = Intent()
59 | intent.data =
60 | Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26jump_from%3Dwebapi%26k%3D$key")
61 | // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
62 | return try {
63 | startActivity(intent)
64 | true
65 | } catch (e: Exception) {
66 | // 未安装手Q或安装的版本不支持
67 | false
68 | }
69 | }
70 |
71 | }
72 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/AppDrawerActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 | import com.yuk.miuiHomeR.utils.ktx.atLeastAndroidS
8 | import moralnorm.preference.Preference
9 |
10 | class AppDrawerActivity : BaseAppCompatActivity() {
11 |
12 | override fun initFragment(): Fragment {
13 | setTitle(R.string.app_drawer)
14 | return AppDrawerFragment()
15 | }
16 |
17 | class AppDrawerFragment : SubFragment() {
18 | override fun getContentResId(): Int {
19 | return R.xml.prefs_app_drawer
20 | }
21 |
22 | override fun initPrefs() {
23 | val mAllAppsBlurVisible = findPreference("prefs_key_home_all_apps_blur")
24 | mAllAppsBlurVisible.isVisible = atLeastAndroidS()
25 | mAllAppsBlurVisible.isEnabled = mAllAppsBlurVisible.isVisible
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/DockActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 | import com.yuk.miuiHomeR.utils.ktx.atLeastAndroidS
8 | import com.yuk.miuiHomeR.utils.ktx.isPadDevice
9 | import moralnorm.preference.Preference
10 |
11 | class DockActivity : BaseAppCompatActivity() {
12 |
13 | override fun initFragment(): Fragment {
14 | setTitle(R.string.dock_settings)
15 | return DockFragment()
16 | }
17 |
18 | class DockFragment : SubFragment() {
19 | override fun getContentResId(): Int {
20 | return R.xml.prefs_dock
21 | }
22 |
23 | override fun initPrefs() {
24 | val mDockVisible = findPreference("prefs_key_home_dock_blur")
25 | mDockVisible.isVisible = !isPadDevice() && atLeastAndroidS()
26 | mDockVisible.isEnabled = mDockVisible.isVisible
27 | val mDockTitleVisible = findPreference("prefs_key_home_dock_icon_title")
28 | mDockTitleVisible.isVisible = !isPadDevice()
29 | mDockTitleVisible.isEnabled = mDockTitleVisible.isVisible
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/FolderActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 | import com.yuk.miuiHomeR.utils.ktx.atLeastAndroidS
8 | import moralnorm.preference.Preference
9 |
10 | class FolderActivity : BaseAppCompatActivity() {
11 |
12 | override fun initFragment(): Fragment {
13 | setTitle(R.string.folder)
14 | return FolderFragment()
15 | }
16 |
17 | class FolderFragment : SubFragment() {
18 | override fun getContentResId(): Int {
19 | return R.xml.prefs_folder
20 | }
21 |
22 | override fun initPrefs() {
23 | val mSmallFolderBlurVisible = findPreference("prefs_key_small_folder_blur")
24 | mSmallFolderBlurVisible.isVisible = atLeastAndroidS()
25 | mSmallFolderBlurVisible.isEnabled = mSmallFolderBlurVisible.isVisible
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/HomeActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 | import com.yuk.miuiHomeR.utils.ktx.atLeastAndroidS
8 | import moralnorm.preference.Preference
9 |
10 | class HomeActivity : BaseAppCompatActivity() {
11 |
12 | override fun initFragment(): Fragment {
13 | setTitle(R.string.home)
14 | return HomeFragment()
15 | }
16 |
17 | class HomeFragment : SubFragment() {
18 | override fun getContentResId(): Int {
19 | return R.xml.prefs_home
20 | }
21 |
22 | override fun initPrefs() {
23 | val mShortcutBlurVisible = findPreference("prefs_key_home_shortcut_blur")
24 | mShortcutBlurVisible.isVisible = atLeastAndroidS()
25 | mShortcutBlurVisible.isEnabled = mShortcutBlurVisible.isVisible
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import android.content.Intent
4 | import android.content.SharedPreferences
5 | import android.content.SharedPreferences.OnSharedPreferenceChangeListener
6 | import android.net.Uri
7 | import android.os.Bundle
8 | import android.os.FileObserver
9 | import android.util.Log
10 | import android.widget.ImageView
11 | import androidx.fragment.app.Fragment
12 | import com.yuk.miuiHomeR.R
13 | import com.yuk.miuiHomeR.provider.SharedPrefsProvider
14 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
15 | import com.yuk.miuiHomeR.ui.base.SubFragment
16 | import com.yuk.miuiHomeR.utils.Helpers
17 | import com.yuk.miuiHomeR.utils.PrefsUtils
18 | import com.yuk.miuiHomeR.utils.ktx.execShell
19 | import moralnorm.preference.Preference
20 | import java.io.File
21 |
22 | class MainActivity : BaseAppCompatActivity() {
23 |
24 | private var fileObserver: FileObserver? = null
25 | private var mPreferenceChangeListener: OnSharedPreferenceChangeListener? = null
26 | private var mActionBarMoreView: ImageView? = null
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | appCompatActionBar.setDisplayHomeAsUpEnabled(intent.getBooleanExtra("homeAsUpEnabled", false))
31 | initView()
32 | initData()
33 | }
34 |
35 | private fun initView() {
36 | mActionBarMoreView = ImageView(this)
37 | mActionBarMoreView!!.setImageResource(R.drawable.ic_settings)
38 | val actionBar = appCompatActionBar
39 | actionBar.endView = mActionBarMoreView
40 | mActionBarMoreView!!.setOnClickListener {
41 | startActivity(
42 | Intent(this, SettingsActivity::class.java)
43 | )
44 | }
45 | }
46 |
47 | private fun initData() {
48 | mPreferenceChangeListener = OnSharedPreferenceChangeListener { sharedPreferences: SharedPreferences, s: String ->
49 | Log.i("prefs", "Changed: $s")
50 | val `val` = sharedPreferences.all[s]
51 | var path = ""
52 | if (`val` is String) path = "string/" else if (`val` is Set<*>) path = "stringset/" else if (`val` is Int) path =
53 | "integer/" else if (`val` is Boolean) path = "boolean/"
54 | contentResolver.notifyChange(Uri.parse("content://" + SharedPrefsProvider.AUTHORITY + "/" + path + s), null)
55 | if (path != "") contentResolver.notifyChange(Uri.parse("content://" + SharedPrefsProvider.AUTHORITY + "/pref/" + path + s), null)
56 | }
57 | PrefsUtils.mSharedPreferences?.registerOnSharedPreferenceChangeListener(mPreferenceChangeListener)
58 | Helpers.fixPermissionsAsync(applicationContext)
59 | try {
60 | fileObserver = object : FileObserver(File(PrefsUtils.sharedPrefsPath), CLOSE_WRITE) {
61 | override fun onEvent(event: Int, path: String?) {
62 | Helpers.fixPermissionsAsync(applicationContext)
63 | }
64 | }
65 | fileObserver?.startWatching()
66 | } catch (t: Throwable) {
67 | Log.e("prefs", "Failed to start FileObserver!")
68 | }
69 | }
70 |
71 | override fun initFragment(): Fragment {
72 | return MainFragment()
73 | }
74 |
75 | class MainFragment : SubFragment(), Preference.OnPreferenceClickListener {
76 | var mRebootHome: Preference? = null
77 | override fun getContentResId(): Int {
78 | return R.xml.prefs_main
79 | }
80 |
81 | override fun initPrefs() {
82 | mRebootHome = findPreference("reboot_home")
83 | mRebootHome?.onPreferenceClickListener = this
84 | }
85 |
86 | override fun onPreferenceClick(preference: Preference): Boolean {
87 | if (preference === mRebootHome) execShell("am force-stop com.miui.home && am force-stop com.yuk.miuiHomeR")
88 | return false
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/OtherActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 |
8 | class OtherActivity : BaseAppCompatActivity() {
9 |
10 | override fun initFragment(): Fragment {
11 | setTitle(R.string.other_features)
12 | return OtherFeaturesFragment()
13 | }
14 |
15 | class OtherFeaturesFragment : SubFragment() {
16 | override fun getContentResId(): Int {
17 | return R.xml.prefs_other
18 | }
19 |
20 | override fun initPrefs() {}
21 | }
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/RecentActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 | import com.yuk.miuiHomeR.utils.ktx.checkMiuiVersion
8 | import moralnorm.preference.Preference
9 |
10 | class RecentActivity : BaseAppCompatActivity() {
11 |
12 | override fun initFragment(): Fragment {
13 | setTitle(R.string.recent)
14 | return RecentFragment()
15 | }
16 |
17 | class RecentFragment : SubFragment() {
18 | override fun getContentResId(): Int {
19 | return R.xml.prefs_recent
20 | }
21 |
22 | override fun initPrefs() {
23 |
24 | val mSmallWindowVisible = findPreference("prefs_key_home_hide_small_window")
25 | mSmallWindowVisible.isVisible = checkMiuiVersion() < 14f
26 | mSmallWindowVisible.isEnabled = mSmallWindowVisible.isVisible
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import android.content.ComponentName
4 | import android.content.Intent
5 | import android.content.pm.PackageManager
6 | import androidx.fragment.app.Fragment
7 | import com.yuk.miuiHomeR.R
8 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
9 | import com.yuk.miuiHomeR.ui.base.SubFragment
10 | import com.yuk.miuiHomeR.utils.BackupUtils
11 | import com.yuk.miuiHomeR.utils.BackupUtils.backup
12 | import com.yuk.miuiHomeR.utils.BackupUtils.handleCreateDocument
13 | import com.yuk.miuiHomeR.utils.BackupUtils.handleReadDocument
14 | import com.yuk.miuiHomeR.utils.BackupUtils.recovery
15 | import com.yuk.miuiHomeR.utils.Locales
16 | import com.yuk.miuiHomeR.utils.PrefsUtils
17 | import moralnorm.preference.DropDownPreference
18 | import moralnorm.preference.Preference
19 | import moralnorm.preference.SwitchPreference
20 | import java.util.Locale
21 |
22 | class SettingsActivity : BaseAppCompatActivity() {
23 |
24 | override fun initFragment(): Fragment {
25 | setTitle(R.string.settings)
26 | return SettingsFragment()
27 | }
28 |
29 | class SettingsFragment : SubFragment(), Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
30 | var mHideIcon: SwitchPreference? = null
31 | var mLocaleSelector: DropDownPreference? = null
32 | var mBackupSettings: Preference? = null
33 | var mRestoreSettings: Preference? = null
34 | override fun getContentResId(): Int {
35 | return R.xml.prefs_settings
36 | }
37 |
38 | override fun initPrefs() {
39 | val mLocaleName = ArrayList()
40 | mHideIcon = findPreference("prefs_key_settings_hide_icon")
41 | mLocaleSelector = findPreference("prefs_key_settings_language")
42 | mBackupSettings = findPreference("prefs_key_settings_backup")
43 | mRestoreSettings = findPreference("prefs_key_settings_restore")
44 | val displayLocaleTags = Locales.DISPLAY_LOCALES
45 | for (displayLocale in displayLocaleTags) {
46 | if (displayLocale == "SYSTEM") {
47 | mLocaleName.add(0, getString(R.string.system_default))
48 | continue
49 | }
50 | val localizedLocale = Locale.forLanguageTag(displayLocale)
51 | mLocaleName.add(localizedLocale.getDisplayName(localizedLocale))
52 | }
53 | mLocaleSelector?.setEntries(mLocaleName.toTypedArray())
54 | mHideIcon?.onPreferenceChangeListener = this
55 | mLocaleSelector?.onPreferenceChangeListener = this
56 | mBackupSettings?.onPreferenceClickListener = this
57 | mRestoreSettings?.onPreferenceClickListener = this
58 | }
59 |
60 | override fun onPreferenceClick(preference: Preference): Boolean {
61 | if (preference === mBackupSettings) {
62 | PrefsUtils.mSharedPreferences?.let { backup(requireActivity(), it) }
63 | } else if (preference === mRestoreSettings) {
64 | PrefsUtils.mSharedPreferences?.let { recovery(requireActivity(), it) }
65 | }
66 | return true
67 | }
68 |
69 | override fun onPreferenceChange(preference: Preference, o: Any): Boolean {
70 | if (preference === mHideIcon) {
71 | val pm = requireActivity().packageManager
72 | val mComponentEnabledState: Int = if (o as Boolean) {
73 | PackageManager.COMPONENT_ENABLED_STATE_ENABLED
74 | } else {
75 | PackageManager.COMPONENT_ENABLED_STATE_DISABLED
76 | }
77 | pm.setComponentEnabledSetting(
78 | ComponentName(requireActivity(), MainActivity::class.java.name + "Alias"),
79 | mComponentEnabledState,
80 | PackageManager.DONT_KILL_APP
81 | )
82 | } else if (preference === mLocaleSelector) {
83 | requireActivity().recreate()
84 | }
85 | return true
86 | }
87 | }
88 |
89 | @Deprecated("Deprecated in Java")
90 | public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
91 | super.onActivityResult(requestCode, resultCode, data)
92 | if (data == null) return
93 | when (requestCode) {
94 | BackupUtils.CREATE_DOCUMENT_CODE -> handleCreateDocument(this, data.data)
95 | BackupUtils.OPEN_DOCUMENT_CODE -> handleReadDocument(this, data.data)
96 | }
97 | }
98 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/WidgetActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui
2 |
3 | import androidx.fragment.app.Fragment
4 | import com.yuk.miuiHomeR.R
5 | import com.yuk.miuiHomeR.ui.base.BaseAppCompatActivity
6 | import com.yuk.miuiHomeR.ui.base.SubFragment
7 |
8 | class WidgetActivity : BaseAppCompatActivity() {
9 |
10 | override fun initFragment(): Fragment {
11 | setTitle(R.string.widget)
12 | return WidgetFragment()
13 | }
14 |
15 | class WidgetFragment : SubFragment() {
16 | override fun getContentResId(): Int {
17 | return R.xml.prefs_widget
18 | }
19 |
20 | override fun initPrefs() {}
21 | }
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/base/BaseAppCompatActivity.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui.base
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.graphics.Color
6 | import android.os.Bundle
7 | import android.view.View
8 | import androidx.fragment.app.Fragment
9 | import com.yuk.miuiHomeR.R
10 | import com.yuk.miuiHomeR.utils.AppManager
11 | import com.yuk.miuiHomeR.utils.ktx.getLocale
12 | import com.yuk.miuiHomeR.utils.ktx.setLocale
13 | import moralnorm.appcompat.app.AppCompatActivity
14 |
15 | import moralnorm.internal.utils.ViewUtils
16 | import java.util.Locale
17 |
18 | abstract class BaseAppCompatActivity : AppCompatActivity() {
19 |
20 | private var mCurrentLocale: Locale? = null
21 | override fun onStart() {
22 | super.onStart()
23 | mCurrentLocale = resources.configuration.locales[0]
24 | }
25 |
26 | override fun onRestart() {
27 | super.onRestart()
28 | val locale: Locale = getLocale(this)
29 | if (locale != mCurrentLocale) {
30 | mCurrentLocale = locale
31 | recreate()
32 | }
33 | }
34 |
35 | override fun attachBaseContext(baseContext: Context) {
36 | super.attachBaseContext(setLocale(baseContext, getLocale(baseContext)))
37 | }
38 |
39 | override fun onCreate(savedInstanceState: Bundle?) {
40 | setTheme(if (ViewUtils.isNightMode(this)) R.style.AppTheme_Dark else R.style.AppTheme)
41 | super.onCreate(savedInstanceState)
42 | AppManager.getInstance().addActivity(this)
43 | setContentView(R.layout.activity_main)
44 | val res = resources
45 | val conf = res.configuration
46 | window.decorView.layoutDirection = conf.layoutDirection
47 | window.statusBarColor = Color.parseColor("#00000000")
48 | window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
49 | supportFragmentManager.beginTransaction().replace(R.id.fragment_container, initFragment()).commit()
50 | }
51 |
52 | abstract fun initFragment(): Fragment
53 |
54 | fun startActivity(activity: AppCompatActivity, cls: Class<*>) {
55 | startActivity(Intent(activity, cls))
56 | }
57 |
58 | override fun onDestroy() {
59 | super.onDestroy()
60 | AppManager.getInstance().removeActivity(this)
61 | }
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/base/BasePreferenceFragment.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui.base
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import com.yuk.miuiHomeR.utils.PrefsUtils
6 | import com.yuk.miuiHomeR.utils.ktx.getLocale
7 | import com.yuk.miuiHomeR.utils.ktx.setLocale
8 | import moralnorm.preference.PreferenceFragmentCompat
9 | import moralnorm.preference.PreferenceManager
10 |
11 | open class BasePreferenceFragment : PreferenceFragmentCompat() {
12 |
13 | override fun onAttach(context: Context) {
14 | super.onAttach(setLocale(context, getLocale(context)))
15 | }
16 |
17 | fun onCreate(savedInstanceState: Bundle?, prefs_default: Int) {
18 | super.onCreate(savedInstanceState)
19 | try {
20 | preferenceManager.sharedPreferencesName = PrefsUtils.mPrefsName
21 | preferenceManager.sharedPreferencesMode = Context.MODE_PRIVATE
22 | preferenceManager.setStorageDeviceProtected()
23 | PreferenceManager.setDefaultValues(requireActivity(), prefs_default, false)
24 | } catch (throwable: Throwable) {
25 | throwable.printStackTrace()
26 | }
27 | }
28 |
29 | override fun onCreatePreferences(bundle: Bundle?, s: String?) {}
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/ui/base/SubFragment.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.ui.base
2 |
3 | import android.os.Bundle
4 |
5 | abstract class SubFragment : BasePreferenceFragment() {
6 |
7 | private var mContentResId = 0
8 | override fun onCreate(savedInstanceState: Bundle?) {
9 | mContentResId = getContentResId()
10 | if (mContentResId != 0) {
11 | super.onCreate(savedInstanceState, mContentResId)
12 | addPreferencesFromResource(mContentResId)
13 | } else {
14 | super.onCreate(savedInstanceState)
15 | }
16 | initPrefs()
17 | }
18 |
19 | abstract fun getContentResId(): Int
20 | abstract fun initPrefs()
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/AppManager.java:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils;
2 |
3 | import android.app.Activity;
4 |
5 | import java.util.Stack;
6 |
7 | public class AppManager {
8 |
9 | private static Stack activityStack;
10 |
11 |
12 | /**
13 | * 单一实例
14 | */
15 | public static AppManager getInstance() {
16 | return SingleApp.INSTANCE;
17 | }
18 |
19 | /**
20 | * 获取指定的Activity
21 | */
22 | public static Activity getActivity(Class> cls) {
23 | if (activityStack != null) for (Activity activity : activityStack) {
24 | if (activity.getClass().equals(cls)) {
25 | return activity;
26 | }
27 | }
28 | return null;
29 | }
30 |
31 | /**
32 | * 添加Activity到堆栈
33 | */
34 | public void addActivity(Activity activity) {
35 | if (activityStack == null) {
36 | activityStack = new Stack<>();
37 | }
38 | activityStack.add(activity);
39 | }
40 |
41 | /**
42 | * 移除Activity
43 | */
44 | public void removeActivity(Activity activity) {
45 | activityStack.remove(activity);
46 | }
47 |
48 | /**
49 | * 获取当前显示Activity(堆栈中最后一个传入的activity)
50 | */
51 | public Activity getLastActivity() {
52 | return activityStack.lastElement();
53 | }
54 |
55 | /**
56 | * 获取所有Activity
57 | */
58 | public Stack getAllActivityStacks() {
59 | return activityStack;
60 | }
61 |
62 | /**
63 | * 结束指定的Activity
64 | */
65 | public void finishActivity(Activity activity) {
66 | if (activity != null) {
67 | if (!activity.isFinishing()) {
68 | activity.finish();
69 | activityStack.remove(activity);
70 | }
71 | }
72 | }
73 |
74 | /**
75 | * 结束指定类名的Activity
76 | */
77 | public void finishActivity(Class> cls) {
78 | for (Activity activity : activityStack) {
79 | if (activity.getClass().equals(cls)) {
80 | finishActivity(activity);
81 | break;
82 | }
83 | }
84 | }
85 |
86 | /**
87 | * 结束除当前传入以外所有Activity
88 | */
89 | public void finishOthersActivity(Class> cls) {
90 | if (activityStack != null) for (Activity activity : activityStack) {
91 | if (!activity.getClass().equals(cls)) {
92 | activity.finish();
93 | }
94 | }
95 | }
96 |
97 | /**
98 | * 结束所有Activity
99 | */
100 | public void finishAllActivity() {
101 | if (activityStack != null) for (Activity activity : activityStack) {
102 | activity.finish();
103 | }
104 | activityStack.clear();
105 | }
106 |
107 | /**
108 | * 退出应用程序
109 | */
110 | public void AppExit() {
111 | try {
112 | finishAllActivity();
113 | android.os.Process.killProcess(android.os.Process.myPid());// 杀死该应用进程
114 | System.exit(0);
115 | } catch (Exception ignore) {
116 | }
117 | }
118 |
119 | public static class SingleApp {
120 | public static final AppManager INSTANCE = new AppManager();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/BackupUtils.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 | import android.content.SharedPreferences
6 | import android.net.Uri
7 | import org.json.JSONObject
8 | import java.io.BufferedReader
9 | import java.io.BufferedWriter
10 | import java.io.InputStreamReader
11 | import java.io.OutputStreamWriter
12 | import java.time.LocalDateTime
13 |
14 | object BackupUtils {
15 | const val CREATE_DOCUMENT_CODE = 255774
16 | const val OPEN_DOCUMENT_CODE = 277451
17 |
18 | private lateinit var sharedPreferences: SharedPreferences
19 |
20 | fun backup(activity: Activity, sp: SharedPreferences) {
21 | sharedPreferences = sp
22 | saveFile(activity, "MiuiHomeR_${LocalDateTime.now()}.json")
23 | }
24 |
25 | fun recovery(activity: Activity, sp: SharedPreferences) {
26 | sharedPreferences = sp
27 | openFile(activity)
28 | }
29 |
30 | private fun openFile(activity: Activity) {
31 | val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
32 | intent.addCategory(Intent.CATEGORY_OPENABLE)
33 | intent.type = "application/json"
34 | intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
35 | activity.startActivityForResult(intent, OPEN_DOCUMENT_CODE)
36 | }
37 |
38 |
39 | private fun saveFile(activity: Activity, fileName: String) {
40 | val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
41 | intent.addCategory(Intent.CATEGORY_OPENABLE)
42 | intent.type = "application/json"
43 | intent.putExtra(Intent.EXTRA_TITLE, fileName)
44 | activity.startActivityForResult(intent, CREATE_DOCUMENT_CODE)
45 | }
46 |
47 | fun handleReadDocument(activity: Activity, data: Uri?) {
48 | val edit = sharedPreferences.edit()
49 | val uri = data ?: return
50 | try {
51 | activity.contentResolver.openInputStream(uri)?.let { loadFile ->
52 | BufferedReader(InputStreamReader(loadFile)).apply {
53 | val sb = StringBuffer()
54 | var line = readLine()
55 | while (line != null) {
56 | sb.append(line)
57 | line = readLine()
58 | }
59 | val read = sb.toString()
60 | JSONObject(read).apply {
61 | val key = keys()
62 | while (key.hasNext()) {
63 | val keys = key.next()
64 | when (val value = get(keys)) {
65 | is String -> if (value.startsWith("Float:")) edit.putFloat(
66 | keys, value.substring(value.indexOf("Float:")).toFloat() / 1000
67 | ) else edit.putString(keys, value)
68 |
69 | is Boolean -> edit.putBoolean(keys, value)
70 | is Int -> edit.putInt(keys, value)
71 | }
72 | }
73 | }
74 | close()
75 | }
76 | }
77 | edit.apply()
78 | } catch (_: Throwable) {
79 | }
80 | }
81 |
82 | fun handleCreateDocument(activity: Activity, data: Uri?) {
83 | val uri = data ?: return
84 | try {
85 | activity.contentResolver.openOutputStream(uri)?.let { saveFile ->
86 | BufferedWriter(OutputStreamWriter(saveFile)).apply {
87 | write(JSONObject().also {
88 | for (entry: Map.Entry in sharedPreferences.all) {
89 | when (entry.value) {
90 | Float -> it.put(entry.key, "Float:" + (entry.value as Float * 1000).toInt().toString())
91 | else -> if (entry.key != "prefs_key_settings_hide_icon") it.put(entry.key, entry.value)
92 | }
93 | }
94 | }.toString())
95 | close()
96 | }
97 | }
98 | } catch (_: Throwable) {
99 | }
100 | }
101 |
102 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/Helpers.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.content.res.Configuration
6 | import android.os.AsyncTask
7 | import com.yuk.miuiHomeR.BuildConfig
8 | import java.io.File
9 |
10 | object Helpers {
11 | const val mAppModulePkg = BuildConfig.APPLICATION_ID
12 |
13 | @Synchronized
14 | fun getProtectedContext(context: Context): Context {
15 | return getProtectedContext(context, null)
16 | }
17 |
18 | @Synchronized
19 | fun getProtectedContext(context: Context, config: Configuration?): Context {
20 | return try {
21 | val mContext = if (context.isDeviceProtectedStorage) context else context.createDeviceProtectedStorageContext()
22 | if (config == null) mContext else mContext.createConfigurationContext(config)
23 | } catch (t: Throwable) {
24 | context
25 | }
26 | }
27 |
28 | @SuppressLint("SetWorldReadable", "SetWorldWritable")
29 | fun fixPermissionsAsync(context: Context) {
30 | AsyncTask.execute {
31 | try {
32 | Thread.sleep(500)
33 | } catch (ignore: Throwable) {
34 | }
35 | val pkgFolder = context.dataDir
36 | if (pkgFolder.exists()) {
37 | pkgFolder.setExecutable(true, false)
38 | pkgFolder.setReadable(true, false)
39 | pkgFolder.setWritable(true, false)
40 | }
41 | val sharedPrefsFolder = File(PrefsUtils.sharedPrefsPath!!)
42 | if (sharedPrefsFolder.exists()) {
43 | sharedPrefsFolder.setExecutable(true, false)
44 | sharedPrefsFolder.setReadable(true, false)
45 | sharedPrefsFolder.setWritable(true, false)
46 | }
47 | val sharedPrefsFile = File(PrefsUtils.sharedPrefsFile!!)
48 | if (sharedPrefsFile.exists()) {
49 | sharedPrefsFile.setReadable(true, false)
50 | sharedPrefsFile.setExecutable(true, false)
51 | sharedPrefsFile.setWritable(true, false)
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/PrefsMap.java:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils;
2 |
3 | import java.util.HashMap;
4 | import java.util.LinkedHashSet;
5 | import java.util.Set;
6 |
7 | public class PrefsMap extends HashMap {
8 |
9 | public Object getObject(String key, Object defValue) {
10 | return get(key) == null ? defValue : get(key);
11 | }
12 |
13 | public int getInt(String key, int defValue) {
14 | key = "prefs_key_" + key;
15 | return get(key) == null ? defValue : (Integer) get(key);
16 | }
17 |
18 | public String getString(String key, String defValue) {
19 | key = "prefs_key_" + key;
20 | return get(key) == null ? defValue : (String) get(key);
21 | }
22 |
23 | public int getStringAsInt(String key, int defValue) {
24 | key = "prefs_key_" + key;
25 | return get(key) == null ? defValue : Integer.parseInt((String) get(key));
26 | }
27 |
28 | @SuppressWarnings("unchecked")
29 | public Set getStringSet(String key) {
30 | key = "prefs_key_" + key;
31 | return get(key) == null ? new LinkedHashSet<>() : (Set) get(key);
32 | }
33 |
34 | public boolean getBoolean(String key) {
35 | key = "prefs_key_" + key;
36 | return get(key) != null && (Boolean) get(key);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/PrefsUtils.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.content.SharedPreferences
6 | import com.yuk.miuiHomeR.utils.Helpers.getProtectedContext
7 | import java.io.File
8 |
9 | object PrefsUtils {
10 | const val mPrefsName = "MiuiHome_Config"
11 | private var mPrefsPathCurrent: String? = null
12 | private var mPrefsFileCurrent: String? = null
13 | var mSharedPreferences: SharedPreferences? = null
14 | private const val mPrefsPath = "/data/user_de/0/" + Helpers.mAppModulePkg + "/shared_prefs"
15 | private const val mPrefsFile = "$mPrefsPath/$mPrefsName.xml"
16 |
17 | @SuppressLint("WorldReadableFiles")
18 | fun getSharedPrefs(context: Context, protectedStorage: Boolean, multiProcess: Boolean): SharedPreferences {
19 | var c = context
20 | if (protectedStorage) c = getProtectedContext(c)
21 | return try {
22 | c.getSharedPreferences(
23 | mPrefsName, if (multiProcess) Context.MODE_MULTI_PROCESS or Context.MODE_WORLD_READABLE else Context.MODE_WORLD_READABLE
24 | )
25 | } catch (t: Throwable) {
26 | c.getSharedPreferences(mPrefsName, if (multiProcess) Context.MODE_MULTI_PROCESS or Context.MODE_PRIVATE else Context.MODE_PRIVATE)
27 | }
28 | }
29 |
30 | fun getSharedPrefs(context: Context, protectedStorage: Boolean): SharedPreferences {
31 | return getSharedPrefs(context, protectedStorage, false)
32 | }
33 |
34 | val sharedPrefsPath: String?
35 | get() = if (mPrefsPathCurrent == null) try {
36 | val mFile = mSharedPreferences!!.javaClass.getDeclaredField("mFile")
37 | mFile.isAccessible = true
38 | mPrefsPathCurrent = (mFile[mSharedPreferences] as File).parentFile?.absolutePath
39 | mPrefsPathCurrent
40 | } catch (t: Throwable) {
41 | print("Test$t")
42 | mPrefsPath
43 | } else mPrefsPathCurrent
44 | val sharedPrefsFile: String?
45 | get() {
46 | if (mPrefsFileCurrent == null) return try {
47 | val fFile = mSharedPreferences!!.javaClass.getDeclaredField("mFile")
48 | fFile.isAccessible = true
49 | mPrefsFileCurrent = (fFile[mSharedPreferences] as File).absolutePath
50 | println("Test: mPrefsFileCurrent")
51 | mPrefsFileCurrent
52 | } catch (t: Throwable) {
53 | println("Test: mPrefsFile$t")
54 | mPrefsFile
55 | } else println("Test: mPrefsFileCurrent2")
56 | return mPrefsFileCurrent
57 | }
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/ResourcesHookData.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils
2 |
3 | data class ResourcesHookData(val type: String, val afterValue: Any)
4 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/ResourcesHookMap.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils
2 |
3 | class ResourcesHookMap : HashMap() {
4 | fun isKeyExist(key: String): Boolean = getOrDefault(key, null) != null
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/yuk/miuiHomeR/utils/ktx/AppUtil.kt:
--------------------------------------------------------------------------------
1 | package com.yuk.miuiHomeR.utils.ktx
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.content.res.Configuration
6 | import android.content.res.Resources
7 | import android.os.Build
8 | import android.text.TextUtils
9 | import android.util.Log
10 | import android.util.TypedValue
11 | import androidx.appcompat.app.AppCompatDelegate
12 | import androidx.core.os.LocaleListCompat
13 | import com.github.kyuubiran.ezxhelper.init.InitFields
14 | import com.yuk.miuiHomeR.utils.PrefsUtils.getSharedPrefs
15 | import moralnorm.internal.utils.DeviceHelper
16 | import java.io.DataOutputStream
17 | import java.util.*
18 |
19 | fun dp2px(dpValue: Float): Int = TypedValue.applyDimension(
20 | TypedValue.COMPLEX_UNIT_DIP, dpValue, InitFields.appContext.resources.displayMetrics
21 | ).toInt()
22 |
23 | fun px2dp(pxValue: Int): Int = (pxValue / InitFields.appContext.resources.displayMetrics.density + 0.5f).toInt()
24 |
25 | fun getDensityDpi(): Int =
26 | (InitFields.appContext.resources.displayMetrics.widthPixels / InitFields.appContext.resources.displayMetrics.density).toInt()
27 |
28 | fun isDarkMode(): Boolean =
29 | InitFields.appContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
30 |
31 | @SuppressLint("PrivateApi")
32 | @Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
33 | fun getProp(mKey: String): String =
34 | Class.forName("android.os.SystemProperties").getMethod("get", String::class.java).invoke(Class.forName("android.os.SystemProperties"), mKey)
35 | .toString()
36 |
37 | @SuppressLint("PrivateApi")
38 | fun getProp(mKey: String, defaultValue: Boolean): Boolean =
39 | Class.forName("android.os.SystemProperties").getMethod("getBoolean", String::class.java, Boolean::class.javaPrimitiveType)
40 | .invoke(Class.forName("android.os.SystemProperties"), mKey, defaultValue) as Boolean
41 |
42 | fun checkVersionName(): String = InitFields.appContext.packageManager.getPackageInfo(
43 | InitFields.appContext.packageName, 0
44 | ).versionName
45 |
46 | fun isAlpha(): Boolean = InitFields.appContext.packageManager.getPackageInfo(
47 | InitFields.appContext.packageName, 0
48 | ).versionName.contains("ALPHA", ignoreCase = true)
49 |
50 | fun isPadDevice(): Boolean = DeviceHelper.isTablet() || DeviceHelper.isFoldDevice()
51 |
52 | fun atLeastAndroidS(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
53 |
54 | fun atLeastAndroidT(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
55 |
56 | fun checkVersionCode(): Long = InitFields.appContext.packageManager.getPackageInfo(
57 | InitFields.appContext.packageName, 0
58 | ).longVersionCode
59 |
60 | fun checkMiuiVersion(): Float = when (getProp("ro.miui.ui.version.name")) {
61 | "V140" -> 14f
62 | "V130" -> 13f
63 | "V125" -> 12.5f
64 | "V12" -> 12f
65 | "V11" -> 11f
66 | "V10" -> 10f
67 | else -> 0f
68 | }
69 |
70 | fun checkAndroidVersion(): String = getProp("ro.build.version.release")
71 |
72 | /**
73 | * 执行 Shell 命令
74 | * @param command Shell 命令
75 | */
76 | fun execShell(command: String) {
77 | try {
78 | val p = Runtime.getRuntime().exec("su")
79 | val outputStream = p.outputStream
80 | val dataOutputStream = DataOutputStream(outputStream)
81 | dataOutputStream.writeBytes(command)
82 | dataOutputStream.flush()
83 | dataOutputStream.close()
84 | outputStream.close()
85 | } catch (t: Throwable) {
86 | t.printStackTrace()
87 | }
88 | }
89 |
90 | @SuppressLint("DiscouragedApi")
91 | fun getCornerRadiusTop(): Int {
92 | val resourceId = InitFields.appContext.resources.getIdentifier(
93 | "rounded_corner_radius_top", "dimen", "android"
94 | )
95 | return if (resourceId > 0) {
96 | InitFields.appContext.resources.getDimensionPixelSize(resourceId)
97 | } else 100
98 | }
99 |
100 | fun setLocale(context: Context, locale: Locale): Context {
101 | var tmpLocale: Locale = locale
102 | if ("und" == locale.toLanguageTag() || "system" == locale.toLanguageTag()) {
103 | tmpLocale = Resources.getSystem().configuration.locales[0]
104 | }
105 | val configuration = context.resources.configuration
106 | configuration.setLocale(tmpLocale)
107 | Log.d("AppUtil", "setLocale: ${tmpLocale.toLanguageTag()}")
108 | if (atLeastAndroidT()) {
109 | AppCompatDelegate.setApplicationLocales(LocaleListCompat.forLanguageTags(tmpLocale.toLanguageTag()))
110 | }
111 | return context.createConfigurationContext(configuration)
112 | }
113 |
114 | fun getLocale(context: Context): Locale {
115 | val pref = getSharedPrefs(context, true)
116 | val tag: String? = pref.getString("prefs_key_settings_language", "SYSTEM")
117 | Log.d("AppUtil", "getLocale: tag=$tag")
118 | return if (tag == null || TextUtils.isEmpty(tag) || "SYSTEM" == tag) {
119 | val sysLang = Resources.getSystem().configuration.locales[0].toLanguageTag().trim()
120 | Log.d("AppUtil", "getLocale: sysLang=$sysLang")
121 | Locale.forLanguageTag(sysLang)
122 | } else Locale.forLanguageTag(tag)
123 | }
124 |
--------------------------------------------------------------------------------
/app/src/main/java/com/zhenxiang/blur/BackgroundBlurDrawableExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.zhenxiang.blur
2 |
3 | import android.os.Build
4 | import androidx.annotation.RequiresApi
5 | import com.android.internal.graphics.drawable.BackgroundBlurDrawable
6 | import org.lsposed.hiddenapibypass.HiddenApiBypass
7 |
8 | @RequiresApi(Build.VERSION_CODES.S)
9 | fun BackgroundBlurDrawable.setColor(color: Int) {
10 | HiddenApiBypass.invoke(BackgroundBlurDrawable::class.java, this, "setColor", color)
11 | }
12 |
13 | @RequiresApi(Build.VERSION_CODES.S)
14 | fun BackgroundBlurDrawable.setBlurRadius(blurRadius: Int) {
15 | HiddenApiBypass.invoke(BackgroundBlurDrawable::class.java, this, "setBlurRadius", blurRadius)
16 | }
17 |
18 | @RequiresApi(Build.VERSION_CODES.S)
19 | fun BackgroundBlurDrawable.setCornerRadius(
20 | cornerRadiusTL: Float,
21 | cornerRadiusTR: Float,
22 | cornerRadiusBL: Float,
23 | cornerRadiusBR: Float
24 | ) {
25 | HiddenApiBypass.invoke(
26 | BackgroundBlurDrawable::class.java,
27 | this,
28 | "setCornerRadius",
29 | cornerRadiusTL,
30 | cornerRadiusTR,
31 | cornerRadiusBL,
32 | cornerRadiusBR
33 | )
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zhenxiang/blur/BlurFrameLayout.kt:
--------------------------------------------------------------------------------
1 | package com.zhenxiang.blur
2 |
3 | import android.content.Context
4 | import android.os.Build
5 | import android.widget.FrameLayout
6 | import androidx.annotation.RequiresApi
7 |
8 | class BlurFrameLayout constructor(context: Context) : FrameLayout(context) {
9 | @RequiresApi(Build.VERSION_CODES.S)
10 | val blurController: SystemBlurController = SystemBlurController(this)
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zhenxiang/blur/BlurLinearLayout.kt:
--------------------------------------------------------------------------------
1 | package com.zhenxiang.blur
2 |
3 | import android.content.Context
4 | import android.os.Build
5 | import android.widget.LinearLayout
6 | import androidx.annotation.RequiresApi
7 |
8 | class BlurLinearLayout constructor(context: Context) : LinearLayout(context) {
9 | @RequiresApi(Build.VERSION_CODES.S)
10 | val blurController: SystemBlurController = SystemBlurController(this)
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zhenxiang/blur/SystemBlurController.kt:
--------------------------------------------------------------------------------
1 | package com.zhenxiang.blur
2 |
3 | import android.content.Context
4 | import android.graphics.Color
5 | import android.graphics.drawable.ShapeDrawable
6 | import android.graphics.drawable.shapes.RoundRectShape
7 | import android.os.Build
8 | import android.view.View
9 | import android.view.WindowManager
10 | import androidx.annotation.RequiresApi
11 | import com.android.internal.graphics.drawable.BackgroundBlurDrawable
12 | import com.yuk.miuiHomeR.mPrefsMap
13 | import com.zhenxiang.blur.model.CornersRadius
14 | import java.util.function.Consumer
15 |
16 | @RequiresApi(Build.VERSION_CODES.S)
17 | class SystemBlurController(
18 | private val view: View,
19 | backgroundColour: Int = if (mPrefsMap.getInt("blur_view_color", -1) != -1) mPrefsMap.getInt("blur_view_color", -1)
20 | else Color.parseColor("#44FFFFFF"),
21 | blurRadius: Int = mPrefsMap.getInt("home_blur_radius", 100),
22 | cornerRadius: CornersRadius = CornersRadius.all(0f),
23 | ) : View.OnAttachStateChangeListener {
24 |
25 | private var windowManager: WindowManager? = null
26 | private val crossWindowBlurListener = Consumer { blurEnabled = it }
27 | private var blurEnabled: Boolean = false
28 | set(value) {
29 | if (value != field) {
30 | field = value
31 | updateBackgroundColour()
32 | updateBlurRadius()
33 | }
34 | }
35 | var backgroundColour = backgroundColour
36 | set(value) {
37 | field = value
38 | updateBackgroundColour()
39 | }
40 | var blurRadius = blurRadius
41 | set(value) {
42 | field = value
43 | updateBlurRadius()
44 | }
45 | var cornerRadius = cornerRadius
46 | set(value) {
47 | field = value
48 | when (val bg = view.background) {
49 | is BackgroundBlurDrawable -> setCornerRadius(bg, value)
50 | is ShapeDrawable -> bg.shape = getShapeFromCorners(value)
51 | }
52 | }
53 |
54 | init {
55 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
56 | // On api 31 and above background init is done in onViewAttachedToWindow
57 | view.addOnAttachStateChangeListener(this)
58 | } else {
59 | // On pre api 31 init background here
60 | val shape = ShapeDrawable()
61 | shape.shape = getShapeFromCorners(cornerRadius)
62 | shape.paint.color = backgroundColour
63 | view.background = shape
64 | }
65 | }
66 |
67 | override fun onViewAttachedToWindow(v: View) {
68 | windowManager = getWindowManager(view.context).apply {
69 | blurEnabled = isCrossWindowBlurEnabled
70 | addCrossWindowBlurEnabledListener(crossWindowBlurListener)
71 | }
72 | view.createBackgroundBlurDrawable()?.let {
73 | // Configure blur drawable with current values
74 | it.setColor(backgroundColour)
75 | it.setBlurRadius(blurRadius)
76 | setCornerRadius(it, cornerRadius)
77 | view.background = it
78 | }
79 | }
80 |
81 | override fun onViewDetachedFromWindow(_v: View) {
82 | // Clear blur drawable
83 | if (view.background is BackgroundBlurDrawable) {
84 | view.background = null
85 | }
86 | windowManager?.removeCrossWindowBlurEnabledListener(crossWindowBlurListener)
87 | windowManager = null
88 | }
89 |
90 | private fun updateBackgroundColour() {
91 | val bg = view.background
92 | when (bg) {
93 | is BackgroundBlurDrawable -> bg.setColor(backgroundColour)
94 | is ShapeDrawable -> bg.paint.color = backgroundColour
95 | }
96 | bg?.invalidateSelf()
97 | }
98 |
99 | private fun updateBlurRadius() {
100 | val bg = view.background
101 | if (bg is BackgroundBlurDrawable) {
102 | bg.setBlurRadius(if (blurEnabled) blurRadius else 0)
103 | }
104 | }
105 |
106 | private fun setCornerRadius(blurDrawable: BackgroundBlurDrawable, corners: CornersRadius) {
107 | blurDrawable.setCornerRadius(
108 | corners.topLeft, corners.topRight, corners.bottomLeft, corners.bottomRight
109 | )
110 | }
111 |
112 | private fun getShapeFromCorners(corners: CornersRadius): RoundRectShape {
113 | return RoundRectShape(getCornersFloatArray(corners), null, null)
114 | }
115 |
116 | private fun getCornersFloatArray(corners: CornersRadius): FloatArray {
117 | return floatArrayOf(
118 | corners.topLeft,
119 | corners.topLeft,
120 | corners.topRight,
121 | corners.topRight,
122 | corners.bottomRight,
123 | corners.bottomRight,
124 | corners.bottomLeft,
125 | corners.bottomLeft
126 | )
127 | }
128 |
129 | private fun getWindowManager(context: Context): WindowManager {
130 | return context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
131 | }
132 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zhenxiang/blur/ViewExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.zhenxiang.blur
2 |
3 | import android.os.Build
4 | import android.util.Log
5 | import android.view.View
6 | import android.view.ViewRootImpl
7 | import androidx.annotation.RequiresApi
8 | import com.android.internal.graphics.drawable.BackgroundBlurDrawable
9 | import org.lsposed.hiddenapibypass.HiddenApiBypass
10 |
11 | @RequiresApi(Build.VERSION_CODES.S)
12 | fun View.createBackgroundBlurDrawable(): BackgroundBlurDrawable? {
13 |
14 | return try {
15 | val getViewRootImpl =
16 | HiddenApiBypass.invoke(View::class.java, this, "getViewRootImpl") as ViewRootImpl
17 | HiddenApiBypass.invoke(
18 | ViewRootImpl::class.java,
19 | getViewRootImpl,
20 | "createBackgroundBlurDrawable"
21 | ) as BackgroundBlurDrawable
22 | } catch (e: Exception) {
23 | Log.w(null, e)
24 | null
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/zhenxiang/blur/model/CornerRadius.kt:
--------------------------------------------------------------------------------
1 | package com.zhenxiang.blur.model
2 |
3 | data class CornersRadius(
4 | val topLeft: Float,
5 | val topRight: Float,
6 | val bottomLeft: Float,
7 | val bottomRight: Float,
8 | ) {
9 |
10 | companion object {
11 | fun all(radius: Float): CornersRadius {
12 | return CornersRadius(radius, radius, radius, radius)
13 | }
14 |
15 | fun custom(
16 | topLeft: Float, topRight: Float, bottomLeft: Float, bottomRight: Float
17 | ): CornersRadius {
18 | return CornersRadius(topLeft, topRight, bottomLeft, bottomRight)
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-440dpi/ic_moralnorm.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/src/main/res/drawable-440dpi/ic_moralnorm.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable-440dpi/ic_yukonga.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/app/src/main/res/drawable-440dpi/ic_yukonga.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
24 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings.xml:
--------------------------------------------------------------------------------
1 |
8 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_task_small_window_dark.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_task_small_window_light.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
23 |
24 |
31 |
32 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/preference_round_layout.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
26 |
27 |
36 |
37 |
42 |
43 |
44 |
45 |
53 |
54 |
63 |
64 |
74 |
75 |
76 |
77 |
78 |
87 |
88 |
96 |
97 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ccffffff
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - com.miui.home
5 |
6 |
7 |
8 | - @string/complete_blur
9 | - @string/test_blur
10 | - @string/simple_blur
11 | - @string/none_blur
12 | - @string/none_blur_simple_anim
13 |
14 |
15 |
16 | - 0
17 | - 1
18 | - 2
19 | - 3
20 | - 4
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #cc000000
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
12 |
13 |
22 |
23 |
27 |
28 |
34 |
35 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
16 |
19 |
20 |
21 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
57 |
58 |
59 |
60 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
72 |
73 |
76 |
77 |
78 |
81 |
82 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_app_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
16 |
17 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_dock.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
20 |
21 |
22 |
30 |
31 |
32 |
41 |
42 |
43 |
51 |
52 |
53 |
61 |
62 |
63 |
72 |
73 |
74 |
83 |
84 |
85 |
93 |
94 |
95 |
99 |
100 |
101 |
109 |
110 |
111 |
119 |
120 |
121 |
125 |
126 |
127 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
12 |
13 |
17 |
18 |
22 |
23 |
27 |
28 |
32 |
33 |
37 |
38 |
42 |
43 |
47 |
48 |
52 |
53 |
57 |
58 |
66 |
67 |
74 |
75 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_other.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
17 |
18 |
22 |
23 |
28 |
29 |
36 |
37 |
44 |
45 |
53 |
54 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_recent.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
14 |
19 |
20 |
24 |
25 |
29 |
30 |
34 |
35 |
39 |
40 |
44 |
45 |
49 |
50 |
54 |
55 |
62 |
63 |
70 |
71 |
79 |
80 |
88 |
89 |
97 |
98 |
106 |
107 |
114 |
115 |
121 |
122 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_widget.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
15 |
16 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.application") version "7.4.0" apply false
3 | id("com.android.library") version "7.4.0" apply false
4 | id("org.jetbrains.kotlin.android") version "1.8.10" apply false
5 | id("dev.rikka.tools.autoresconfig") version "1.2.2" apply false
6 | }
7 |
8 | tasks.register("clean").configure {
9 | delete(rootProject.buildDir)
10 | }
11 |
--------------------------------------------------------------------------------
/crowdin.yml:
--------------------------------------------------------------------------------
1 | files:
2 | - source: /app/src/main/res/values/strings.xml
3 | translation: /app/src/main/res/values-%two_letters_code%/strings.xml
4 |
--------------------------------------------------------------------------------
/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gradle
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | target-branch: main
8 |
--------------------------------------------------------------------------------
/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=-Xmx2048m -Dfile.encoding=UTF-8
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 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | #android.enableJetifier=true
20 | android.enableR8.fullMode=true
21 | android.enableAppCompileTimeRClass=true
22 | android.nonTransitiveRClass=true
23 | org.gradle.caching=true
24 | org.gradle.parallel=true
25 | org.gradle.vfs.watch=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qqlittleice/MiuiHome_R/9f3a298df6427b3a8ea6a47aaabfa0a56c4dd11e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionPath=wrapper/dists
2 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/hidden-api/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/hidden-api/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | id("org.jetbrains.kotlin.android")
4 | }
5 |
6 | android {
7 | compileSdk = 33
8 | namespace = "com.android.internal"
9 | buildTypes {
10 | release {
11 | isMinifyEnabled = false
12 | setProguardFiles(listOf(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"))
13 | }
14 | }
15 | compileOptions {
16 | sourceCompatibility = JavaVersion.VERSION_11
17 | targetCompatibility = JavaVersion.VERSION_11
18 | }
19 | kotlinOptions {
20 | jvmTarget = JavaVersion.VERSION_11.majorVersion
21 | }
22 | }
23 |
24 | dependencies {
25 | implementation("androidx.annotation:annotation:1.5.0")
26 | }
27 |
--------------------------------------------------------------------------------
/hidden-api/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
--------------------------------------------------------------------------------
/hidden-api/src/main/java/android/view/ViewRootImpl.java:
--------------------------------------------------------------------------------
1 | package android.view;
2 |
3 | import android.os.Build;
4 |
5 | import androidx.annotation.RequiresApi;
6 |
7 | import com.android.internal.graphics.drawable.BackgroundBlurDrawable;
8 |
9 | public class ViewRootImpl {
10 | @RequiresApi(Build.VERSION_CODES.S)
11 | public BackgroundBlurDrawable createBackgroundBlurDrawable() {
12 | throw new RuntimeException("Stub!");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/hidden-api/src/main/java/com/android/internal/graphics/drawable/BackgroundBlurDrawable.java:
--------------------------------------------------------------------------------
1 | package com.android.internal.graphics.drawable;
2 |
3 | import android.graphics.drawable.Drawable;
4 | import android.os.Build;
5 |
6 | import androidx.annotation.RequiresApi;
7 |
8 | @RequiresApi(Build.VERSION_CODES.S)
9 | public abstract class BackgroundBlurDrawable extends Drawable { }
10 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | google()
5 | mavenCentral()
6 | }
7 | }
8 |
9 | dependencyResolutionManagement {
10 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11 | repositories {
12 | google()
13 | mavenCentral()
14 | maven("https://jitpack.io")
15 | maven("https://api.xposed.info")
16 | }
17 | }
18 |
19 | include(":app", ":hidden-api")
20 | rootProject.name = "MiuiHomeR"
21 |
--------------------------------------------------------------------------------