Skip to content

Instantly share code, notes, and snippets.

@Terrance
Last active April 17, 2025 22:23
Show Gist options
  • Save Terrance/bf44bf556d55da65de3fe88a69fa7116 to your computer and use it in GitHub Desktop.
Save Terrance/bf44bf556d55da65de3fe88a69fa7116 to your computer and use it in GitHub Desktop.
Script to list installed apps on Android from the output of `dumpsys package packages`.
#!/usr/bin/env python3
from collections import defaultdict
import subprocess
USERS = {"0": "main", "10": "work"}
def style(text, *codes):
return "\33[{}m{}\33[0m".format(";".join(str(code) for code in codes), text)
def main():
dumpsys = subprocess.run(("/system/bin/dumpsys", "package", "packages"), capture_output=True)
uids = {}
installers = defaultdict(set)
flags = defaultdict(set)
states = defaultdict(dict)
tags = defaultdict(set)
for line in dumpsys.stdout.decode().splitlines():
if line.startswith(" Package ["):
package = line.split("[")[1].split("]")[0]
elif line.startswith(" userId="):
uids[package] = line.split("=", 1)[1]
elif line.startswith(" installerPackageName="):
installer = line.split("=", 1)[1]
installers[installer].add(package)
elif line.startswith(" flags="):
flags[package] = set(line.split("[", 1)[1].rsplit("]", 1)[0].split())
elif line.startswith(" User "):
user, meta = line[9:].split(": ", 1)
args = dict(flag.split("=", 1) for flag in meta.split())
if args["installed"] == "true":
states[package][user] = args["enabled"] in ("0", "1")
installed = {package for packages in installers.values() for package in packages}
for package in uids:
if package not in installed:
installers[""].add(package)
for installer, packages in sorted(installers.items()):
if installer:
print()
print(style(installer, 1))
for package in sorted(packages):
uid = uids[package]
if "SYSTEM" in flags[package]:
tag = style("sys", 35)
elif "DEBUGGABLE" in flags[package]:
tag = style("dbg", 33)
else:
tag = " "
users = []
enabled = False
for user, name in USERS.items():
if user not in states[package]:
part = " "
elif states[package][user]:
enabled = True
part = " {} ".format(name)
else:
part = style("({})".format(name), 31)
users.append(part)
if not enabled:
package = style(package, 31)
print(f" {uid:<5} {tag} {' '.join(users)} {package}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment