From 18d4ccfab2291a42626f9f339f164409310762b5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 23:06:24 +0000 Subject: [PATCH 1/2] feat: add ADB debloat script for Xiaomi/Redmi/HyperOS phones Non-root pm uninstall --user 0 based debloater with a curated, tiered package list (safe third-party bloat vs. opt-in Xiaomi/HyperOS apps vs. documented do-not-touch), a dry-run mode, and restore/restore-all to reverse any removal. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_019Uo91Mmg5jG3o7DsTjzVk5 --- android/README.md | 75 ++++++++ android/redmi_debloat.sh | 383 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 458 insertions(+) create mode 100644 android/README.md create mode 100755 android/redmi_debloat.sh diff --git a/android/README.md b/android/README.md new file mode 100644 index 0000000..fea63fc --- /dev/null +++ b/android/README.md @@ -0,0 +1,75 @@ +# Redmi / Xiaomi ADB Debloat + +Non-root ADB debloat helper for Xiaomi/Redmi/POCO phones running HyperOS +(or MIUI). Written for a Redmi Note 15 5G, but the package lists apply to +most recent HyperOS devices. + +## Prep (do this before connecting the phone) + +1. Install Android platform-tools (`adb`) on this machine: + - Fedora/RHEL: `sudo dnf install android-tools` + - Debian/Ubuntu: `sudo apt install android-sdk-platform-tools` + - Arch: `sudo pacman -S android-tools` +2. On the phone: **Settings > About phone**, tap "HyperOS version" (or "MIUI + version") 7 times to unlock Developer options. +3. **Settings > Additional settings > Developer options**: enable + **USB debugging**. On MIUI/HyperOS also enable **USB debugging (Security + settings)** if you plan to use `install-existing`/`uninstall` for system + apps - some ROMs gate `pm uninstall` behind it. +4. Connect the phone by USB cable, unlock it, and accept the "Allow USB + debugging?" prompt (tick "always allow from this computer"). +5. Verify: `adb devices` should show the device as `device`, not + `unauthorized` or `offline`. + +## Usage + +```bash +cd android +./redmi_debloat.sh info # print all known packages, no device needed +./redmi_debloat.sh list # show which of them are actually installed +./redmi_debloat.sh remove --dry-run # preview what `remove` would do +./redmi_debloat.sh remove # remove Tier 1 (safe) only +./redmi_debloat.sh remove --include-miui # also remove Tier 2 (Xiaomi bundled apps) +./redmi_debloat.sh restore com.miui.notes # bring one package back +./redmi_debloat.sh restore-all removed-packages-*.txt # bring everything back +``` + +Every `remove` run writes a `removed-packages-.txt` file with +exactly what it removed, so a bad call is one `restore-all` away from fixed. + +## How it works + +Uses `adb shell pm uninstall -k --user 0 `. This does **not** +delete the system APK - it just hides the app from the current user profile +and keeps its data (`-k`). Nothing here needs root, and everything is +undone by `restore`/`restore-all`, or trivially by a factory reset. + +## Package tiers + +- **Tier 1 - safe**: ordinary third-party apps Xiaomi/carriers bundle + (Facebook, Amazon, Netflix, LinkedIn, Opera, Microsoft Office, WPS + Office, bundled games, etc). These are regular user apps, not system + components - removing them is as safe as uninstalling any app from the + launcher. +- **Tier 2 - opt-in (`--include-miui`)**: Xiaomi/HyperOS-branded bundled + apps and services (Mi Browser, Mi Video/Music, GetApps-adjacent extras, + `com.miui.analytics`, `com.miui.msa.global` ad services). Low risk for + most people, but skipped by default since a couple of these touch + account/cloud features some users keep. +- **Tier 3 - documented only, never touched by the script**: packages + where sources actively disagree, or where real breakage has been + reported (`com.miui.daemon` and Cloud SMS verification, `com.android.stk` + and banking apps, `com.xiaomi.xmsf` and OTA updates, etc). Run + `./redmi_debloat.sh info` to see the full list with the reasoning for + each. Leave these alone. + +## Sources + +Package lists and risk notes were compiled from: + +- [Minimal Xiaomi/Redmi Debloat List (Android 15 / HyperOS 2, 06/2025)](https://gist.github.com/gabeweb/a126aa204c2c08882ed192e16173457c) +- [matthieu-pierson/debloat-hyperos-adb](https://github.com/matthieu-pierson/debloat-hyperos-adb) +- [leechuanfeng/hyperos-debloat](https://github.com/leechuanfeng/hyperos-debloat) + +Bloatware varies by region, carrier and HyperOS version, so always run +`list` first and read `info`'s notes before using `--include-miui`. diff --git a/android/redmi_debloat.sh b/android/redmi_debloat.sh new file mode 100755 index 0000000..5cbeff1 --- /dev/null +++ b/android/redmi_debloat.sh @@ -0,0 +1,383 @@ +#!/usr/bin/env bash +# +# Redmi / Xiaomi HyperOS ADB Debloat Script (standalone) +# +# Removes pre-installed bloatware from a Xiaomi/Redmi/POCO phone over ADB, +# without root. Uses `pm uninstall -k --user 0`, which only hides the app +# for the current user and keeps the system APK + data, so everything is +# reversible with `restore` until a factory reset. +# +# Requires: `adb` (Android platform-tools) on this machine, and USB +# debugging enabled + authorized on the phone (Settings > About phone > +# tap "MIUI/HyperOS version" 7x > Developer options > USB debugging). +# +# See README.md in this directory for the full package tier explanation +# and sources. +# + +set -euo pipefail + +# ============================================================================ +# Common Helper Functions +# The same helpers are used in every bash script in this repo, so the +# scripts stay consistent while remaining standalone single-file downloads. +# Function names follow the PowerShell Verb-Noun convention. +# ============================================================================ + +# shellcheck disable=SC2034 # not every script uses every color +readonly RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' \ + BLUE='\033[0;34m' PURPLE='\033[0;35m' BOLD='\033[1m' NC='\033[0m' + +# Optional plain-text logfile; set LOG_FILE after this block to enable. +LOG_FILE="${LOG_FILE:-}" + +# Usage: Write-Log "message" +Write-Log() { + local level=$1; shift + local color=$NC + case $level in + INFO) color=$BLUE ;; + SUCCESS) color=$GREEN ;; + WARN) color=$YELLOW ;; + ERROR) color=$RED ;; + STEP) color=$PURPLE ;; + esac + if [[ $level == ERROR ]]; then + echo -e "${color}[$level]${NC} $*" >&2 + else + echo -e "${color}[$level]${NC} $*" + fi + if [[ -n "$LOG_FILE" ]]; then + echo "[$level] $*" >> "$LOG_FILE" + fi +} + +# Usage: Stop-Script "fatal message" +Stop-Script() { + Write-Log ERROR "$1" + exit 1 +} + +# ============================================================================ +# Package Lists +# +# Tier 1 (safe): regular preinstalled third-party apps (games, shopping, +# social, office). These are ordinary user apps, not system components - +# removing them carries essentially no risk. +# +# Tier 2 (miui): Xiaomi/HyperOS-branded bundled apps and services (Mi +# Browser, Mi Video/Music, GetApps ecosystem extras, analytics/ads). Safe +# for most people but opt-in via --include-miui since a few overlap with +# account/cloud features some users rely on. +# +# Tier 3 (do-not-remove, documented only, never touched by this script): +# packages where sources conflict or where removal has caused real +# breakage. Printed by `info` so you know to leave them alone. +# ============================================================================ + +readonly TIER1_SAFE=( + # Third-party bloat / regional partner apps + com.facebook.appmanager com.facebook.katana com.facebook.orca + com.facebook.services com.facebook.system + com.amazon.appmanager com.amazon.fv com.amazon.kindle com.amazon.mp3 + com.amazon.mshop.android com.amazon.mshop.android.shopping com.amazon.venezia + com.netflix.mediaclient com.netflix.partner.activation + com.spotify.music com.linkedin.android com.booking com.tripadvisor.tripadvisor + com.alibaba.aliexpresshd com.einnovation.temu com.zhiliaoapp.musically + com.opera.browser com.opera.max.oem com.opera.preinstall + com.microsoft.office.excel com.microsoft.office.officehubrow + com.microsoft.office.outlook com.microsoft.office.powerpoint + com.microsoft.office.word com.microsoft.skydrive + cn.wps.moffice_eng cn.wps.xiaomi.abroad.lite com.infraware.polarisoffice5 + com.google.android.apps.magazines com.google.android.apps.books + com.google.android.apps.docs com.google.android.apps.tachyon + com.google.android.apps.youtube.music com.google.android.videos + com.google.android.music com.google.android.printservice.recommendation + com.mi.global.pocobbs com.mi.global.pocostore + com.audible.application com.imdb.mobile com.flipboard.app com.flipboard.boxer.app + com.touchtype.swiftkey com.sohu.inputmethod.sogou.xiaomi + com.xiaomi.discover com.xiaomi.midrop com.xiaomi.ugd + # Bundled games (names vary by region/campaign, harmless to skip if absent) + com.block.juggle com.block.puzzle.game.hippo.mi com.crazy.juicer.xm + com.fugo.wow com.funtomic.matchmasters com.gameduell.tarot + com.jewelsblast.ivygames.adventure.free com.nf.snake com.oakever.tiletrip + com.plarium.raidlegends com.soulcompany.bubbleshooter.relaxing + com.sukhavati.gotoplaying.bubble.bubbleshooter.mint com.tripledot.solitaire + com.vitastudio.mahjong net.wooga.junes_journey_hidden_object_mystery_game +) + +readonly TIER2_MIUI=( + com.mi.globalbrowser com.mi.globalminusscreen + com.miui.videoplayer com.miui.player com.miui.yellowpage com.miui.compass + com.miui.extraphoto com.miui.notes com.miui.weather2 com.miui.misightservice + com.miui.analytics com.miui.msa.global + com.xiaomi.payment com.xiaomi.barrage com.xiaomi.simactivate.service + com.android.providers.partnerbookmarks + com.tencent.soter.soterserver org.ifaa.aidl.manager com.qti.dcf +) + +# Documented only - `info` prints these, `remove` never touches them even +# with --include-miui. Sources disagree on some (see README), so the safe +# default is: leave alone. +readonly TIER3_DO_NOT_REMOVE_DOC=( + "com.miui.daemon|core system daemon; removal has been reported to break Xiaomi Cloud SMS verification" + "com.android.stk|SIM Toolkit; some banking/carrier apps depend on it" + "com.android.incallui|the phone call UI itself" + "com.android.contacts|the default Contacts app/provider UI" + "com.miui.miservice|conflicting reports: one source lists it as safe MI-service cleanup, another says it's required for Bluetooth - not worth the risk" + "com.xiaomi.joyose|game-performance daemon; low impact idle, but leave it if you play games" + "com.qti.qcc|Qualcomm service some games (e.g. Monopoly GO) require" + "com.miui.miwallpaper|needed for lock screen wallpaper rendering" + "com.xiaomi.xmsf|Xiaomi Mi Service Framework; needed for OTA system updates" +) + +# ============================================================================ +# ADB Helpers +# ============================================================================ + +Test-Adb() { + command -v adb >/dev/null 2>&1 || Stop-Script "adb not found. Install Android platform-tools first." +} + +# Usage: Test-DeviceConnected (exits with guidance if 0 or >1 devices, or unauthorized) +Test-DeviceConnected() { + local lines + lines=$(adb devices | tail -n +2 | sed '/^$/d') + + local count + count=$(echo "$lines" | grep -c . || true) + + if [[ $count -eq 0 ]]; then + Stop-Script "No device found. Enable USB debugging (Settings > Additional settings > Developer options) and plug in the phone." + fi + + if echo "$lines" | grep -q unauthorized; then + Stop-Script "Device listed as 'unauthorized'. Accept the 'Allow USB debugging?' prompt on the phone screen." + fi + + if [[ $count -gt 1 ]]; then + Stop-Script "Multiple devices/emulators connected. Disconnect the others first." + fi + + echo "$lines" | grep -q device$ || Stop-Script "Device is not ready (state: $lines). Check the USB connection." +} + +# Usage: packages=$(Get-InstalledPackages) - full "com.example.app" list, one per line +Get-InstalledPackages() { + adb shell pm list packages | tr -d '\r' | sed 's/^package://' +} + +# Usage: Test-PackageInstalled "$installed_list" "com.example.app" +Test-PackageInstalled() { + local installed=$1 pkg=$2 + grep -qx "$pkg" <<< "$installed" +} + +# Usage: Remove-Package "com.example.app" +Remove-Package() { + local pkg=$1 + if adb shell pm uninstall -k --user 0 "$pkg" 2>&1 | grep -q Success; then + Write-Log SUCCESS "Removed: $pkg" + return 0 + else + Write-Log WARN "Failed to remove: $pkg (may be protected on this ROM)" + return 1 + fi +} + +# Usage: Restore-Package "com.example.app" +Restore-Package() { + local pkg=$1 + if adb shell pm install-existing --user 0 "$pkg" 2>&1 | grep -q Installed; then + Write-Log SUCCESS "Restored: $pkg" + else + Write-Log ERROR "Failed to restore: $pkg (it may have been a Tier 1 app removed via the Play Store path, or is gone after a factory reset)" + fi +} + +# ============================================================================ +# Commands +# ============================================================================ + +Show-Usage() { + cat <<'EOF' +Usage: redmi_debloat.sh [options] + +Commands: + list Show which known bloat packages are installed on the connected device + remove Uninstall (for current user) matched packages; writes a restore file + restore Reinstall one package for the current user + restore-all Reinstall every package listed in a file produced by `remove` + info Print all known packages per tier with explanation (no device needed) + +Options (remove): + --include-miui Also remove Tier 2 (Xiaomi/HyperOS bundled apps), not just Tier 1 + --dry-run Show what would be removed without doing it + -y, --yes Skip the confirmation prompt + +Examples: + ./redmi_debloat.sh info + ./redmi_debloat.sh list + ./redmi_debloat.sh remove --dry-run + ./redmi_debloat.sh remove --include-miui + ./redmi_debloat.sh restore com.miui.notes + ./redmi_debloat.sh restore-all removed-packages-20260906-120000.txt + +See README.md for background on the package tiers and sources. +EOF +} + +Get-MatchedPackages() { + local installed=$1 include_miui=$2 + local pkg + for pkg in "${TIER1_SAFE[@]}"; do + Test-PackageInstalled "$installed" "$pkg" && echo "$pkg" + done + if [[ $include_miui == true ]]; then + for pkg in "${TIER2_MIUI[@]}"; do + Test-PackageInstalled "$installed" "$pkg" && echo "$pkg" + done + fi + return 0 +} + +Show-InstalledMatches() { + Test-Adb + Test-DeviceConnected + Write-Log INFO "Reading installed packages from device..." + local installed + installed=$(Get-InstalledPackages) + + Write-Log STEP "Tier 1 (safe, third-party bloat) found on device:" + Get-MatchedPackages "$installed" false | sed 's/^/ - /' + + Write-Log STEP "Tier 2 (Xiaomi/HyperOS bundled apps, opt-in) found on device:" + local pkg + for pkg in "${TIER2_MIUI[@]}"; do + Test-PackageInstalled "$installed" "$pkg" && echo " - $pkg" + done + return 0 +} + +Show-Info() { + Write-Log STEP "Tier 1 - safe to remove (third-party bloat, ${#TIER1_SAFE[@]} packages):" + printf ' %s\n' "${TIER1_SAFE[@]}" + echo + Write-Log STEP "Tier 2 - opt-in via --include-miui (Xiaomi/HyperOS bundled apps, ${#TIER2_MIUI[@]} packages):" + printf ' %s\n' "${TIER2_MIUI[@]}" + echo + Write-Log STEP "Tier 3 - do NOT remove (documented only):" + local entry + for entry in "${TIER3_DO_NOT_REMOVE_DOC[@]}"; do + printf ' %-32s %s\n' "${entry%%|*}" "${entry#*|}" + done +} + +Remove-MatchedPackages() { + local include_miui=$1 dry_run=$2 assume_yes=$3 + + Test-Adb + Test-DeviceConnected + Write-Log INFO "Reading installed packages from device..." + local installed + installed=$(Get-InstalledPackages) + + local matches + matches=$(Get-MatchedPackages "$installed" "$include_miui") + + if [[ -z "$matches" ]]; then + Write-Log INFO "No known bloat packages found installed. Nothing to do." + return 0 + fi + + Write-Log STEP "The following packages will be removed for the current user:" + echo "$matches" | sed 's/^/ - /' + + if [[ $dry_run == true ]]; then + Write-Log INFO "Dry run, no changes made." + return 0 + fi + + if [[ $assume_yes != true ]]; then + read -r -p "Proceed? [y/N]: " response + [[ "$response" =~ ^[Yy]$ ]] || Stop-Script "Aborted" + fi + + local restore_file + restore_file="removed-packages-$(date +%Y%m%d-%H%M%S).txt" + : > "$restore_file" + + local pkg failed=0 + while IFS= read -r pkg; do + if Remove-Package "$pkg"; then + echo "$pkg" >> "$restore_file" + else + failed=$((failed + 1)) + fi + done <<< "$matches" + + Write-Log SUCCESS "Done. Restore list saved to: $restore_file" + [[ $failed -eq 0 ]] || Write-Log WARN "$failed package(s) could not be removed, see warnings above." +} + +Restore-One() { + local pkg=${1:-} + [[ -n "$pkg" ]] || Stop-Script "Usage: restore " + Test-Adb + Test-DeviceConnected + Restore-Package "$pkg" +} + +Restore-FromFile() { + local file=${1:-} + [[ -n "$file" ]] || Stop-Script "Usage: restore-all " + [[ -f "$file" ]] || Stop-Script "File not found: $file" + Test-Adb + Test-DeviceConnected + + local pkg + while IFS= read -r pkg; do + [[ -n "$pkg" ]] || continue + Restore-Package "$pkg" + done < "$file" +} + +# ============================================================================ +# Main Entry Point +# ============================================================================ + +case "${1:-}" in + list) + Show-InstalledMatches + ;; + info) + Show-Info + ;; + remove) + shift + include_miui=false dry_run=false assume_yes=false + while [[ $# -gt 0 ]]; do + case "$1" in + --include-miui) include_miui=true; shift ;; + --dry-run) dry_run=true; shift ;; + -y|--yes) assume_yes=true; shift ;; + *) Stop-Script "Unknown option for 'remove': $1" ;; + esac + done + Remove-MatchedPackages "$include_miui" "$dry_run" "$assume_yes" + ;; + restore) + Restore-One "${2:-}" + ;; + restore-all) + Restore-FromFile "${2:-}" + ;; + -h|--help|"") + Show-Usage + ;; + *) + Write-Log ERROR "Unknown command: $1" + Show-Usage + exit 1 + ;; +esac From 88c8d6dec89312ef3faaf01dbf0c536cf875dc35 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 23:07:20 +0000 Subject: [PATCH 2/2] docs: clarify HyperOS 3 compatibility for the Redmi debloat script Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_019Uo91Mmg5jG3o7DsTjzVk5 --- android/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/android/README.md b/android/README.md index fea63fc..f8d55f6 100644 --- a/android/README.md +++ b/android/README.md @@ -1,8 +1,9 @@ # Redmi / Xiaomi ADB Debloat Non-root ADB debloat helper for Xiaomi/Redmi/POCO phones running HyperOS -(or MIUI). Written for a Redmi Note 15 5G, but the package lists apply to -most recent HyperOS devices. +(or MIUI). Written for a Redmi Note 15 5G on HyperOS 3, but the package +lists apply just as well to HyperOS 2 devices - community reports confirm +no significant bloatware changes between the two. ## Prep (do this before connecting the phone) @@ -70,6 +71,7 @@ Package lists and risk notes were compiled from: - [Minimal Xiaomi/Redmi Debloat List (Android 15 / HyperOS 2, 06/2025)](https://gist.github.com/gabeweb/a126aa204c2c08882ed192e16173457c) - [matthieu-pierson/debloat-hyperos-adb](https://github.com/matthieu-pierson/debloat-hyperos-adb) - [leechuanfeng/hyperos-debloat](https://github.com/leechuanfeng/hyperos-debloat) +- [XDA: HyperOS 2/3 debloat guide & package list](https://xdaforums.com/t/how-to-debloat-hyperos-2-3-updated-list-of-packages-apps-200-tutorial-video-4-ways-methods-2026.4775822/) Bloatware varies by region, carrier and HyperOS version, so always run `list` first and read `info`'s notes before using `--include-miui`.