├── .gitattributes ├── .gitignore ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── xayah │ │ └── imghelper │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── Bin.zip │ │ ├── Patch.sh │ │ ├── magiskboot │ │ └── util_functions.sh │ ├── ic_launcher-playstore.png │ ├── java │ │ └── com │ │ │ └── xayah │ │ │ └── imghelper │ │ │ ├── App.kt │ │ │ ├── MainActivity.kt │ │ │ ├── MainViewModel.kt │ │ │ ├── fragment │ │ │ ├── about │ │ │ │ ├── AboutFragment.kt │ │ │ │ └── AboutViewModel.kt │ │ │ ├── dtbo │ │ │ │ ├── DTBOFragment.kt │ │ │ │ └── DTBOViewModel.kt │ │ │ ├── home │ │ │ │ ├── HomeFragment.kt │ │ │ │ └── HomeViewModel.kt │ │ │ ├── pack │ │ │ │ ├── PackFragment.kt │ │ │ │ └── PackViewModel.kt │ │ │ └── unpack │ │ │ │ ├── UnpackFragment.kt │ │ │ │ └── UnpackViewModel.kt │ │ │ └── util │ │ │ ├── Path.kt │ │ │ ├── ShellUtil.kt │ │ │ └── Tool.kt │ └── res │ │ ├── animator │ │ ├── nav_default_enter_anim.xml │ │ ├── nav_default_exit_anim.xml │ │ ├── nav_default_pop_enter_anim.xml │ │ └── nav_default_pop_exit_anim.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── coolapk_1394294.png │ │ ├── ic_baseline_vpn_key.xml │ │ ├── ic_clash.xml │ │ ├── ic_dtbo.xml │ │ ├── ic_dtbo_copyright.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_outline_archive.xml │ │ ├── ic_outline_home.xml │ │ ├── ic_outline_unarchive.xml │ │ ├── ic_round_apps.xml │ │ ├── ic_round_architecture.xml │ │ ├── ic_round_content_cut.xml │ │ └── ic_round_flash.xml │ │ ├── layout │ │ ├── about_fragment.xml │ │ ├── activity_main.xml │ │ ├── dtbo_fragment.xml │ │ ├── home_fragment.xml │ │ ├── pack_fragment.xml │ │ └── unpack_fragment.xml │ │ ├── menu │ │ └── bottom_navigation.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ └── navigation_main.xml │ │ ├── values-night │ │ ├── colors.xml │ │ └── themes.xml │ │ ├── values-v29 │ │ └── themes.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── xayah │ └── imghelper │ └── ExampleUnitTest.kt ├── build.gradle ├── design ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── xayah │ │ └── design │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── xayah │ │ │ └── design │ │ │ ├── ActionLabel.kt │ │ │ ├── LargeActionCard.kt │ │ │ ├── LargeActionLabel.kt │ │ │ ├── adapter │ │ │ └── ViewAdapter.kt │ │ │ ├── preference │ │ │ ├── Category.kt │ │ │ ├── Clickable.kt │ │ │ ├── EditableText.kt │ │ │ ├── Preference.kt │ │ │ ├── Screen.kt │ │ │ ├── SelectableList.kt │ │ │ └── Switch.kt │ │ │ └── util │ │ │ └── Theme.kt │ └── res │ │ ├── layout │ │ ├── component_action_label.xml │ │ ├── component_large_action_label.xml │ │ ├── dialog_text_field.xml │ │ ├── preference_category.xml │ │ ├── preference_clickable.xml │ │ └── preference_switch.xml │ │ ├── values-night │ │ └── colors.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── xayah │ └── design │ └── ExampleUnitTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /release -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'kotlin-kapt' 5 | } 6 | 7 | android { 8 | compileSdkVersion 32 9 | buildToolsVersion "30.0.3" 10 | 11 | viewBinding { 12 | enabled = true 13 | } 14 | 15 | dataBinding { 16 | enabled = true 17 | } 18 | 19 | defaultConfig { 20 | applicationId "com.xayah.imghelper" 21 | minSdkVersion 26 22 | targetSdkVersion 32 23 | versionCode 9 24 | versionName "2.0.5" 25 | 26 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 27 | } 28 | 29 | buildTypes { 30 | release { 31 | minifyEnabled false 32 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 33 | } 34 | } 35 | compileOptions { 36 | sourceCompatibility JavaVersion.VERSION_1_8 37 | targetCompatibility JavaVersion.VERSION_1_8 38 | } 39 | kotlinOptions { 40 | jvmTarget = '1.8' 41 | } 42 | } 43 | 44 | dependencies { 45 | implementation 'androidx.core:core-ktx:1.7.0' 46 | implementation 'androidx.appcompat:appcompat:1.3.1' 47 | implementation 'com.google.android.material:material:1.5.0' 48 | implementation 'androidx.constraintlayout:constraintlayout:2.0.4' 49 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 50 | testImplementation 'junit:junit:4.13.2' 51 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 52 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 53 | 54 | // Libsu 55 | def libsuVersion = '4.0.0' 56 | // The core module is used by all other components 57 | implementation "com.github.topjohnwu.libsu:core:${libsuVersion}" 58 | // Optional: APIs for creating root services 59 | implementation "com.github.topjohnwu.libsu:service:${libsuVersion}" 60 | // Optional: For com.topjohnwu.superuser.io classes 61 | implementation "com.github.topjohnwu.libsu:io:${libsuVersion}" 62 | // Optional: Bundle prebuilt BusyBox binaries 63 | implementation "com.github.topjohnwu.libsu:busybox:${libsuVersion}" 64 | 65 | def lifecycle_version = "2.4.0" 66 | // ViewModel 67 | implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version") 68 | // ViewModel utilities for Compose 69 | implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version") 70 | // LiveData 71 | implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version") 72 | implementation "androidx.activity:activity-ktx:1.3.1" 73 | implementation "androidx.fragment:fragment-ktx:1.3.6" 74 | 75 | // Navigation 76 | def nav_version = "2.3.5" 77 | implementation("androidx.navigation:navigation-fragment-ktx:$nav_version") 78 | implementation("androidx.navigation:navigation-ui-ktx:$nav_version") 79 | 80 | // MaterialYouFileExplorer 81 | implementation 'io.github.xayahsususu:materialyoufileexplorer:1.0.5' 82 | 83 | // Design 84 | implementation project(path: ':design') 85 | } -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /app/src/androidTest/java/com/xayah/imghelper/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.xayah.imghelper 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("com.xayah.imghelper", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/assets/Bin.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XayahSuSuSu/Android-IMGHelper/7131696df6eed334bd0f5214693e295bdb4b2375/app/src/main/assets/Bin.zip -------------------------------------------------------------------------------- /app/src/main/assets/Patch.sh: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | # Authored: Shenlhz 3 | # Adjust: Xayah 4 | 5 | input_img=$1 6 | output_dir=$2 7 | info=$3 8 | mkdtimg dump $input_img -b dtb 9 | for i in `find dtb.*`; do 10 | dtc -I dtb -O dts -@ $i -o $i.dts 11 | mv $i.dts dts.$i 12 | done 13 | rm -rf dtb.* 14 | rm -rf dts 15 | mkdir dts 16 | mv dts.dtb.* dts 17 | hz=`printf %x $info` 18 | Patch1=`grep -l -r -n "qcom,mdss-dsi-panel-framerate = <0x3c>" ./dts` 19 | sed -i "s/qcom,mdss-dsi-panel-framerate = <0x3c>/qcom,mdss-dsi-panel-framerate = <0x$hz>/g" $Patch1 20 | var=`expr "scale=5;$info / 60"|bc` 21 | var2=`expr "$var * 1100000000"|bc` 22 | var3=`printf %x $var2` 23 | Patch2=`grep -l -r -n "qcom,mdss-dsi-panel-clockrate = <0x4190ab00>" ./dts` 24 | sed -i "s/qcom,mdss-dsi-panel-clockrate = <0x4190ab00>/qcom,mdss-dsi-panel-clockrate = <0x$var3>/g" $Patch2 25 | mv ./dts/dts.dtb.* ./ 26 | rm -rf dts 27 | for i in `find dts.dtb.*`; do 28 | dtc -I dts -O dtb -@ -o $i.dtb $i 29 | mv $i.dtb dtb.$i 30 | done 31 | rm -rf dts.dtb.* 32 | mkdtimg create dtbo_new.img dtb.dts.dtb.* 33 | rm -rf dtb.dts.dtb.* 34 | mv dtbo_new.img $output_dir -------------------------------------------------------------------------------- /app/src/main/assets/magiskboot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XayahSuSuSu/Android-IMGHelper/7131696df6eed334bd0f5214693e295bdb4b2375/app/src/main/assets/magiskboot -------------------------------------------------------------------------------- /app/src/main/assets/util_functions.sh: -------------------------------------------------------------------------------- 1 | ############################################ 2 | # Magisk General Utility Functions 3 | ############################################ 4 | 5 | MAGISK_VER='24.2' 6 | MAGISK_VER_CODE=24200 7 | 8 | ################### 9 | # Helper Functions 10 | ################### 11 | 12 | ui_print() { 13 | if $BOOTMODE; then 14 | echo "$1" 15 | else 16 | echo -e "ui_print $1\nui_print" >> /proc/self/fd/$OUTFD 17 | fi 18 | } 19 | 20 | toupper() { 21 | echo "$@" | tr '[:lower:]' '[:upper:]' 22 | } 23 | 24 | grep_cmdline() { 25 | local REGEX="s/^$1=//p" 26 | { echo $(cat /proc/cmdline)$(sed -e 's/[^"]//g' -e 's/""//g' /proc/cmdline) | xargs -n 1; \ 27 | sed -e 's/ = /=/g' -e 's/, /,/g' -e 's/"//g' /proc/bootconfig; \ 28 | } 2>/dev/null | sed -n "$REGEX" 29 | } 30 | 31 | grep_prop() { 32 | local REGEX="s/^$1=//p" 33 | shift 34 | local FILES=$@ 35 | [ -z "$FILES" ] && FILES='/system/build.prop' 36 | cat $FILES 2>/dev/null | dos2unix | sed -n "$REGEX" | head -n 1 37 | } 38 | 39 | grep_get_prop() { 40 | local result=$(grep_prop $@) 41 | if [ -z "$result" ]; then 42 | # Fallback to getprop 43 | getprop "$1" 44 | else 45 | echo $result 46 | fi 47 | } 48 | 49 | getvar() { 50 | local VARNAME=$1 51 | local VALUE 52 | local PROPPATH='/data/.magisk /cache/.magisk' 53 | [ ! -z $MAGISKTMP ] && PROPPATH="$MAGISKTMP/config $PROPPATH" 54 | VALUE=$(grep_prop $VARNAME $PROPPATH) 55 | [ ! -z $VALUE ] && eval $VARNAME=\$VALUE 56 | } 57 | 58 | is_mounted() { 59 | grep -q " $(readlink -f $1) " /proc/mounts 2>/dev/null 60 | return $? 61 | } 62 | 63 | abort() { 64 | ui_print "$1" 65 | $BOOTMODE || recovery_cleanup 66 | [ ! -z $MODPATH ] && rm -rf $MODPATH 67 | rm -rf $TMPDIR 68 | exit 1 69 | } 70 | 71 | resolve_vars() { 72 | MAGISKBIN=$NVBASE/magisk 73 | POSTFSDATAD=$NVBASE/post-fs-data.d 74 | SERVICED=$NVBASE/service.d 75 | } 76 | 77 | print_title() { 78 | local len line1len line2len bar 79 | line1len=$(echo -n $1 | wc -c) 80 | line2len=$(echo -n $2 | wc -c) 81 | len=$line2len 82 | [ $line1len -gt $line2len ] && len=$line1len 83 | len=$((len + 2)) 84 | bar=$(printf "%${len}s" | tr ' ' '*') 85 | ui_print "$bar" 86 | ui_print " $1 " 87 | [ "$2" ] && ui_print " $2 " 88 | ui_print "$bar" 89 | } 90 | 91 | ###################### 92 | # Environment Related 93 | ###################### 94 | 95 | setup_flashable() { 96 | ensure_bb 97 | $BOOTMODE && return 98 | if [ -z $OUTFD ] || readlink /proc/$$/fd/$OUTFD | grep -q /tmp; then 99 | # We will have to manually find out OUTFD 100 | for FD in `ls /proc/$$/fd`; do 101 | if readlink /proc/$$/fd/$FD | grep -q pipe; then 102 | if ps | grep -v grep | grep -qE " 3 $FD |status_fd=$FD"; then 103 | OUTFD=$FD 104 | break 105 | fi 106 | fi 107 | done 108 | fi 109 | recovery_actions 110 | } 111 | 112 | ensure_bb() { 113 | if set -o | grep -q standalone; then 114 | # We are definitely in busybox ash 115 | set -o standalone 116 | return 117 | fi 118 | 119 | # Find our busybox binary 120 | local bb 121 | if [ -f $TMPDIR/busybox ]; then 122 | bb=$TMPDIR/busybox 123 | elif [ -f $MAGISKBIN/busybox ]; then 124 | bb=$MAGISKBIN/busybox 125 | else 126 | abort "! Cannot find BusyBox" 127 | fi 128 | chmod 755 $bb 129 | 130 | # Busybox could be a script, make sure /system/bin/sh exists 131 | if [ ! -f /system/bin/sh ]; then 132 | umount -l /system 2>/dev/null 133 | mkdir -p /system/bin 134 | ln -s $(command -v sh) /system/bin/sh 135 | fi 136 | 137 | export ASH_STANDALONE=1 138 | 139 | # Find our current arguments 140 | # Run in busybox environment to ensure consistent results 141 | # /proc//cmdline shall be