Skip to content

Instantly share code, notes, and snippets.

@ankurpandeyvns
Created February 7, 2026 15:47
Show Gist options
  • Select an option

  • Save ankurpandeyvns/ef92dd43f5632bc60c5d975e4d058d2e to your computer and use it in GitHub Desktop.

Select an option

Save ankurpandeyvns/ef92dd43f5632bc60c5d975e4d058d2e to your computer and use it in GitHub Desktop.
#!/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