Created
February 7, 2026 15:47
-
-
Save ankurpandeyvns/ef92dd43f5632bc60c5d975e4d058d2e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # Pixel Photos Debloat Script | |
| # Strips a Pixel device down to only what's needed for Google Photos + Play Store. | |
| # Uses pm uninstall -k --user 0 (reversible, keeps data). | |
| # | |
| # Usage: | |
| # ./pixel-photos-debloat.sh # debloat connected device | |
| # ./pixel-photos-debloat.sh --restore # restore all removed packages | |
| # ./pixel-photos-debloat.sh --dry-run # show what would be removed | |
| # ./pixel-photos-debloat.sh --list # list currently installed packages | |
| set -euo pipefail | |
| # --- Package lists --- | |
| CARRIER_BLOAT=( | |
| com.verizon.services | |
| com.verizon.llkagent | |
| com.vzw.apnlib | |
| com.verizon.obdm_permissions | |
| com.verizon.obdm | |
| com.customermobile.preload.vzw | |
| com.android.vzwomatrigger | |
| com.google.android.wfcactivation | |
| com.google.android.tetheringentitlement | |
| com.android.sdm.plugins.connmo | |
| com.android.sdm.plugins.dcmo | |
| com.android.sdm.plugins.diagmon | |
| com.android.sdm.plugins.sprintdm | |
| com.google.android.hiddenmenu | |
| com.android.omadm.service | |
| com.google.android.carrier | |
| com.google.android.carriersetup | |
| com.google.android.ims | |
| com.google.android.apps.carrier.log | |
| ) | |
| TELEPHONY_SIM=( | |
| com.android.stk | |
| com.android.simappdialog | |
| com.android.cellbroadcastreceiver | |
| com.android.mms.service | |
| com.android.providers.blockednumber | |
| com.android.calllogbackup | |
| org.codeaurora.ims | |
| com.android.service.ims.presence | |
| com.android.service.ims | |
| com.android.ons | |
| com.android.carrierdefaultapp | |
| com.android.emergency | |
| ) | |
| QUALCOMM_TELEPHONY=( | |
| com.qualcomm.qcrilmsgtunnel | |
| com.qualcomm.atfwd | |
| com.qualcomm.embms | |
| com.qualcomm.fastdormancy | |
| com.qualcomm.qti.ims | |
| com.qualcomm.qti.telephonyservice | |
| com.qualcomm.qti.radioconfiginterface | |
| com.qualcomm.qti.rcsbootstraputil | |
| com.qualcomm.ltebc_vzw | |
| qualcomm.com.vzw_msdc_api | |
| com.qti.qualcomm.datastatusnotification | |
| ) | |
| GOOGLE_APPS=( | |
| com.google.android.youtube | |
| com.google.android.apps.docs | |
| com.google.android.calendar | |
| com.google.android.calculator | |
| com.google.android.gm | |
| com.google.android.music | |
| com.google.android.videos | |
| com.google.android.apps.maps | |
| com.google.android.contacts | |
| com.google.android.syncadapters.contacts | |
| com.google.android.tts | |
| com.google.android.apps.messaging | |
| com.google.android.dialer | |
| com.google.android.googlequicksearchbox | |
| com.google.android.apps.pixelmigrate | |
| com.google.android.contactkeys | |
| com.google.android.projection.gearhead | |
| com.google.android.apps.enterprise.dmagent | |
| com.google.android.apps.cloudprint | |
| com.google.android.markup | |
| com.google.android.deskclock | |
| com.google.android.soundpicker | |
| com.google.android.marvin.talkback | |
| com.google.android.GoogleCamera | |
| com.google.android.apps.wallpaper | |
| com.google.android.apps.wallpaper.nexus | |
| com.google.android.apps.wellbeing | |
| com.google.android.apps.safetyhub | |
| com.google.android.apps.turbo | |
| com.google.android.hardwareinfo | |
| com.google.android.apps.helprtc | |
| com.google.android.feedback | |
| com.google.android.as | |
| com.google.ar.core | |
| com.google.vr.vrcore | |
| com.google.vr.apps.ornament | |
| com.android.chrome | |
| ) | |
| SYSTEM_BLOAT=( | |
| com.android.nfc | |
| com.google.android.tag | |
| com.android.hotwordenrollment.okgoogle | |
| com.android.hotwordenrollment.xgoogle | |
| com.android.facelock | |
| com.google.android.apps.work.oobconfig | |
| com.android.dreams.basic | |
| com.android.egg | |
| com.android.wallpaper.livepicker | |
| com.ustwo.lwp | |
| com.breel.geswallpapers | |
| com.android.htmlviewer | |
| com.android.bookmarkprovider | |
| com.android.providers.partnerbookmarks | |
| com.android.bips | |
| com.google.android.printservice.recommendation | |
| com.android.printspooler | |
| com.android.bluetoothmidiservice | |
| com.android.companiondevicemanager | |
| com.android.mtp | |
| com.android.musicfx | |
| com.android.hotspot2 | |
| com.android.safetyregulatoryinfo | |
| com.android.traceur | |
| com.android.wallpaperbackup | |
| com.android.managedprovisioning | |
| com.android.dynsystem | |
| com.android.providers.calendar | |
| com.android.providers.userdictionary | |
| com.android.se | |
| com.htc.omadm.trigger | |
| com.android.backupconfirm | |
| com.google.android.onetimeinitializer | |
| com.android.localtransport | |
| com.android.sharedstoragebackup | |
| com.android.statementservice | |
| ) | |
| IME_STUBS=( | |
| com.google.android.apps.inputmethod.hindi | |
| com.google.android.inputmethod.japanese | |
| com.google.android.inputmethod.pinyin | |
| com.google.android.inputmethod.korean | |
| ) | |
| # Combine all | |
| ALL_PACKAGES=( | |
| "${CARRIER_BLOAT[@]}" | |
| "${TELEPHONY_SIM[@]}" | |
| "${QUALCOMM_TELEPHONY[@]}" | |
| "${GOOGLE_APPS[@]}" | |
| "${SYSTEM_BLOAT[@]}" | |
| "${IME_STUBS[@]}" | |
| ) | |
| # --- Functions --- | |
| check_device() { | |
| if ! command -v adb &>/dev/null; then | |
| echo "ERROR: adb not found in PATH" | |
| exit 1 | |
| fi | |
| local devices | |
| devices=$(adb devices | grep -c 'device$' || true) | |
| if [[ "$devices" -eq 0 ]]; then | |
| echo "ERROR: No ADB device connected" | |
| echo "Connect via USB or run: adb connect <ip>:5555" | |
| exit 1 | |
| fi | |
| echo "Device connected: $(adb devices | grep 'device$' | awk '{print $1}')" | |
| } | |
| get_installed() { | |
| adb shell pm list packages 2>/dev/null | sed 's/package://' | sort | |
| } | |
| debloat() { | |
| local dry_run="${1:-false}" | |
| local installed | |
| installed=$(get_installed) | |
| local total=0 success=0 skipped=0 failed=0 | |
| declare -A CATEGORIES=( | |
| ["Carrier/Verizon bloat"]="CARRIER_BLOAT" | |
| ["Telephony/SIM"]="TELEPHONY_SIM" | |
| ["Qualcomm telephony"]="QUALCOMM_TELEPHONY" | |
| ["Unused Google apps"]="GOOGLE_APPS" | |
| ["System bloat"]="SYSTEM_BLOAT" | |
| ["IME stubs"]="IME_STUBS" | |
| ) | |
| local ORDER=("Carrier/Verizon bloat" "Telephony/SIM" "Qualcomm telephony" "Unused Google apps" "System bloat" "IME stubs") | |
| for category in "${ORDER[@]}"; do | |
| local var="${CATEGORIES[$category]}" | |
| local -n pkgs="$var" | |
| local cat_count=0 | |
| echo "" | |
| echo "=== $category ===" | |
| for pkg in "${pkgs[@]}"; do | |
| total=$((total + 1)) | |
| if ! echo "$installed" | grep -qx "$pkg"; then | |
| skipped=$((skipped + 1)) | |
| continue | |
| fi | |
| if [[ "$dry_run" == "true" ]]; then | |
| echo " [DRY-RUN] Would remove: $pkg" | |
| cat_count=$((cat_count + 1)) | |
| success=$((success + 1)) | |
| else | |
| if adb shell pm uninstall -k --user 0 "$pkg" 2>/dev/null | grep -q "Success"; then | |
| echo " [OK] $pkg" | |
| cat_count=$((cat_count + 1)) | |
| success=$((success + 1)) | |
| else | |
| echo " [FAIL] $pkg" | |
| failed=$((failed + 1)) | |
| fi | |
| fi | |
| done | |
| if [[ $cat_count -eq 0 ]]; then | |
| echo " (nothing to remove)" | |
| fi | |
| done | |
| echo "" | |
| echo "================================" | |
| if [[ "$dry_run" == "true" ]]; then | |
| echo "DRY RUN SUMMARY" | |
| else | |
| echo "DEBLOAT SUMMARY" | |
| fi | |
| echo " Removed: $success" | |
| echo " Skipped: $skipped (not installed)" | |
| echo " Failed: $failed" | |
| echo " Total: $total" | |
| echo "================================" | |
| if [[ "$dry_run" != "true" && $success -gt 0 ]]; then | |
| echo "" | |
| echo "All removals are reversible. To restore:" | |
| echo " ./pixel-photos-debloat.sh --restore" | |
| fi | |
| } | |
| restore() { | |
| local total=0 success=0 failed=0 | |
| echo "Restoring all previously removed packages..." | |
| echo "" | |
| for pkg in "${ALL_PACKAGES[@]}"; do | |
| total=$((total + 1)) | |
| result=$(adb shell cmd package install-existing "$pkg" 2>&1) | |
| if echo "$result" | grep -qi "installed"; then | |
| echo " [RESTORED] $pkg" | |
| success=$((success + 1)) | |
| else | |
| failed=$((failed + 1)) | |
| fi | |
| done | |
| echo "" | |
| echo "================================" | |
| echo "RESTORE SUMMARY" | |
| echo " Restored: $success" | |
| echo " Failed: $failed (may not have been removed)" | |
| echo " Total: $total" | |
| echo "================================" | |
| } | |
| list_packages() { | |
| echo "Currently installed packages:" | |
| echo "" | |
| get_installed | |
| echo "" | |
| echo "Total: $(get_installed | wc -l | tr -d ' ') packages" | |
| } | |
| usage() { | |
| echo "Pixel Photos Debloat - Strip device to Google Photos essentials" | |
| echo "" | |
| echo "Usage: $0 [option]" | |
| echo "" | |
| echo "Options:" | |
| echo " (none) Remove all unnecessary packages" | |
| echo " --dry-run Show what would be removed without doing it" | |
| echo " --restore Restore all previously removed packages" | |
| echo " --list List currently installed packages" | |
| echo " --help Show this help" | |
| echo "" | |
| echo "Kept packages:" | |
| echo " Google Photos, Play Store, Play Services, GSF" | |
| echo " Pixel Launcher, Gboard, WebView, Magisk" | |
| echo " Core system (SystemUI, Settings, providers, network)" | |
| } | |
| # --- Main --- | |
| case "${1:-}" in | |
| --help|-h) | |
| usage | |
| ;; | |
| --dry-run) | |
| check_device | |
| debloat true | |
| ;; | |
| --restore) | |
| check_device | |
| restore | |
| ;; | |
| --list) | |
| check_device | |
| list_packages | |
| ;; | |
| "") | |
| check_device | |
| echo "" | |
| echo "This will remove ~94 packages from the device." | |
| echo "Removals are reversible via --restore." | |
| echo "" | |
| read -rp "Proceed? [y/N] " confirm | |
| if [[ "$confirm" =~ ^[Yy]$ ]]; then | |
| debloat false | |
| else | |
| echo "Aborted." | |
| fi | |
| ;; | |
| *) | |
| echo "Unknown option: $1" | |
| usage | |
| exit 1 | |
| ;; | |
| esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment