Lab 0 — Set up
Get a device or emulator, a working adb, and the habits that keep a lab safe: know what you are connecting to, what state it is in, and how to get back to normal.
Every lab in this module assumes one thing: you have a device you are allowed to poke at, and
adb can see it. This page gets you there and establishes the safety habits that make the rest of
the labs non-destructive.
TL;DR#
- One device at a time.
adb deviceslists what is connected;-s <serial>targets one. - Developer options and USB debugging must be enabled before
adbcan talk to a phone. - An emulator is a fine lab device and is easier to reset than a phone.
- Read before you write. Start with commands that only print state.
- Know the undo. A setting you changed with
settings putcan be changed back; a package you disabled can be re-enabled.
Mental model#
Think of adb as a remote control with a shell attached.
The remote control part talks to a daemon on the device, which is why the device has to permit it: USB debugging is the permission, and the RSA key prompt is the authentication.
The shell part runs commands as the shell user on the device. That user has more access than
an app but less than root, which is why some commands in these labs work and others do not.
Where the analogy breaks#
A remote control has a fixed set of buttons. adb shell gives you a shell, so the set of things you
can do is limited by the device's permissions rather than by the tool. That is why the labs teach
commands rather than features: the same adb binary runs every one of them.
Deep dive#
Connecting#
Over USB. Enable developer options (tap Build number seven times in About phone), then enable USB debugging in developer options. Connect the cable and accept the RSA fingerprint prompt on the device.
Over the network. Android supports wireless debugging on modern devices through a pairing flow
in developer options. The adb pair command pairs with the device using a code the device displays,
and adb connect then connects to the debugging port.1
The first thing to run in every session:
adb devices -lThe -l adds model and device information, which is how you tell two connected devices apart. If
the list shows unauthorized, the device has not accepted your key; if it shows offline, the
connection is not established.
The shell user#
adb shell runs as the shell UID on the device. That is a privileged user: it can read many
system files, call most system services, and change settings. It is not root, and it is not the
system UID, so some operations will be refused.
Three consequences worth knowing before the labs:
dumpsysis available to shell for most services. That is why it is the backbone of these labs.settingscan read and write the settings database for the namespaces shell is allowed to touch.- Package commands can change state — disabling, granting, revoking — and those changes persist until you undo them.
The safety habits#
Read the current value before changing it. For any setting, run settings get first, and keep
the output. That is your undo.
Prefer reversible commands. pm disable-user can be undone with pm enable. pm uninstall
cannot, unless you reinstall.
Do not disable system packages you depend on. Disabling the launcher or SystemUI will leave you with a device that is hard to use. The labs avoid this, but the command exists.
Know how to recover. A device stuck in a strange state usually recovers with a reboot. An emulator can be wiped and restarted.
The commands you will use most#
| Command | What it does |
|---|---|
adb devices -l | List connected devices with details |
adb shell | Open a shell as the shell user |
adb shell getprop | Read system properties |
adb shell dumpsys <service> | Print a system service's state |
adb shell pm list packages | List installed packages |
adb shell am start -W | Start an activity and wait for the result |
adb shell cmd <service> <command> | Call a service's command interface |
adb logcat | Read the log buffers |
adb pull <path> | Copy a file from the device |
A first session#
- Confirm the device
Run
adb devices -l. If the state isunauthorized, unlock the phone and accept the prompt. If it isoffline, reconnect the cable or restart the adb server.You should seeOne line per connected device, with a serial and a state of device. - Read the build identity
Run the four
getpropcommands below. Note the API level; several labs choose behaviour based on it.You should seeFour lines, each a value. - List the services
Run
adb shell dumpsys -l. This is the map for every dumpsys lab. Look foractivity,package,window,meminfoandbatterystats.You should seeA long list of service names, one per line. - Open a shell
Run
adb shell. Tryidto see which user you are, thenexit.You should seeA shell prompt on the device.
adb devices -l
adb shell getprop ro.build.version.release
adb shell getprop ro.build.version.sdk
adb shell getprop ro.product.model
adb shell getprop ro.build.version.security_patch
adb shell dumpsys -l
adb shell idExample output
Illustrative output — your device will differ.Challenges#
Challenge 1 — Identify the device#
Without looking at the phone, determine its model, its Android version and its API level.
Reveal the answer
adb shell getprop ro.product.model
adb shell getprop ro.build.version.release
adb shell getprop ro.build.version.sdkro.product.model is the marketing model; ro.build.version.release is the Android version;
ro.build.version.sdk is the API level. If several devices are attached, add -s <serial> or set
ANDROID_SERIAL.
Challenge 2 — Find the service that owns the status bar#
dumpsys -l lists service names, not descriptions. Which service would you dump to learn about
the status bar and notification shade?
Reveal the answer
The statusbar service. Try:
adb shell dumpsys statusbarThe service is managed by SystemUI rather than system_server, which is why it has its own dump
implementation. Related services include notification and window.
Challenge 3 — Prove you are not root#
Show that the shell user cannot read another app's private data directory.
Reveal the answer
adb shell id
adb shell ls /data/dataid reports uid=2000(shell), not root. Listing /data/data is refused for most entries because
each app's directory is protected by its UID and by SELinux. This is the sandbox in action; the
security module explains the mechanism.
What you learned#
You have a device, a shell, and a map of its services. Every later lab starts from here. If you want the background on why the shell user is privileged but not root, read The app sandbox.
Next#
Lab 1 — Processes starts with the process table, which is the single most useful view of a running Android system.
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsadb over Wi-Fideveloper.android.comaccessed 2026-10-27↩
- docsdumpsysdeveloper.android.comaccessed 2026-10-27↩
- docsAndroid Debug Bridge (adb)developer.android.comaccessed 2026-10-27↩
- docsBuild Androidsource.android.comaccessed 2026-10-27↩