Zygote
Hands-on labsintermediate

Lab 2 — Services

Go inside system_server: list the registered Binder services, read which process hosts each one, and use service call and cmd to talk to a service without writing any code.

5 minAPI 1–37 · 17verified 2026-10-27

Every framework call you make ends up at a registered Binder service. This lab shows you the registry, the processes behind it, and two ways to call a service from the shell without writing an app.

TL;DR#

  • service list prints every registered Binder service and its interface descriptor.
  • Most framework services live in system_server; some are hosted by native processes.
  • dumpsys <name> calls the service's dump method — a read-only view.
  • cmd <name> <command> calls the service's command interface, which can change state.
  • service call sends a raw transaction by code number, which is the lowest-level tool and the easiest to misuse.

Mental model#

Think of a building directory.

The directory board is ServiceManager: a list of names and the office each one occupies. It does not know what the offices do; it only knows where they are.

The office is the service. It has a door (the Binder interface), an intercom (the transaction protocol) and a filing cabinet (its state).

The visitor is your app or your shell command. You look up the name, get a handle, and talk through the door.

Where the analogy breaks#

A building directory lists physical offices in one building. ServiceManager lists Binder services across processes: some are in system_server, some in native daemons, some in app processes. The directory is a single namespace over many processes, which is what makes it useful and also what makes "which process hosts this?" a separate question.

Deep dive#

The registry#

adb shell service list

Each line has a name and an interface descriptor, for example activity: [android.app.IActivityManager]. The descriptor is the AIDL interface the service implements, which is how a client knows what methods are available.

The list is long — over a hundred entries on a modern device. Some names are familiar (activity, package, window, notification); others are internal (media.player, stats, usb).

Which process hosts a service#

service list does not tell you the host process. The reliable way to find out is to check where the service's code lives:

  • system_server hosts the framework services: activity, package, window, notification, alarm, and most of the android.* managers.
  • Native processes host media, audio, camera and surface services: media.*, audio_flinger, SurfaceFlinger.
  • App processes can host services too, especially in Mainline modules and in apps that publish a Binder interface.

A quick way to confirm is to look at ps for the process, then dumpsys the service and read the header. Many dump outputs name the hosting process.

Reading a service's dump#

adb shell dumpsys activity

This is the service telling you its state in its own words. Every service implements dump differently, which is why dumpsys output looks inconsistent between services: there is no schema, only whatever the author decided to print.

Useful patterns:

  • dumpsys activity activities — the activity stack.
  • dumpsys activity services — running services.
  • dumpsys package — installed packages and their state.
  • dumpsys window — windows, displays and insets.

Calling a service: cmd#

cmd is the supported way to run a service command from the shell. It is a Binder call with a string command and arguments, and the service decides what to do.

adb shell cmd package list packages
adb shell cmd activity get-config

The available commands are service-specific. Two ways to discover them:

adb shell cmd -l
adb shell cmd <service> help

cmd is preferred over service call because it is typed, documented by the service, and stable. It can change state, so read the help before running a command you do not know.

Calling a service: service call#

service call sends a raw transaction to a Binder service by transaction code. It is the lowest-level tool available from the shell, and it is mostly useful for confirming that a service is alive and that a transaction code is what you think it is.

adb shell service call <name> <code> <arguments>

The arguments are typed and parcel-formatted, which is why this is not a general-purpose tool: you need the interface definition to know the codes and the argument layout. The Android source is the only reliable reference.

Walkthrough#

  1. List the services

    adb shell service list

    You should seeA long list of name: [interface] lines.
  2. Count them

    adb shell service list | wc -l

    You should seeA number above one hundred on a modern device.
  3. Find the activity service

    adb shell service list | grep -E "^.*activity"

    You should seeA line naming activity and its interface.
  4. Read its state

    adb shell dumpsys activity | head -60

    You should seeA long dump with the activity stack and process records.
  5. Use the command interface

    adb shell cmd -l adb shell cmd package list packages | head}

    You should seeThe service's help text or a list of packages.
Service registry
adb shell service list
adb shell service list | wc -l
adb shell dumpsys activity | head -60
adb shell cmd -l
adb shell cmd package list packages | head
Example output
Illustrative output — service names and counts differ per device.

Challenges#

Challenge 1 — Find a service that is not in system_server#

Pick a service from service list that is hosted by a native process, and prove it.

Reveal the answer

Try SurfaceFlinger:

adb shell service list | grep -i surface
adb shell ps -A | grep surfaceflinger
adb shell dumpsys SurfaceFlinger | head -20

The service is registered in the same namespace, but the process is surfaceflinger, a native daemon started by init. The registry does not care which process hosts a service; that is the point of a handle-based namespace.

Challenge 2 — Read a service's own help#

Find the commands a service supports without guessing.

Reveal the answer
adb shell cmd -l
adb shell cmd package help

cmd -l lists the services with a command interface. cmd <service> help asks that service for its own command list. It is the supported discovery path and it is more reliable than reading a wiki.

Challenge 3 — Tell dump from command#

Explain why dumpsys is safe to run casually and cmd is not.

Reveal the answer

dumpsys calls a dump method whose contract is to print state. It is read-only in practice: a well-behaved service does not mutate state in dump. cmd calls a command interface whose methods are designed to change state — install, enable, set, force-stop. Both run as the shell user, so both are limited by shell's permissions, but only one of them is meant to be a mutation.

What you learned#

You can now find a service, identify its host process, read its state and call its command interface. That is the practical version of the framework's client-server architecture.

Next#

Lab 3 — Packages looks at the package manager, which is the service that knows what is installed.

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.

  1. docsAndroid Debug Bridge (adb)developer.android.comaccessed 2026-10-27↩
  2. docsdumpsysdeveloper.android.comaccessed 2026-10-27↩
  3. docsBinder overviewsource.android.comaccessed 2026-10-27↩
  4. docsAndroid platform architecture (AOSP)source.android.comaccessed 2026-10-27↩
  5. docsAndroid Interface Definition Language (AIDL) | Background workdeveloper.android.comaccessed 2026-10-27↩