Advanced AOSP Subsystems
2 min read

Triggers

Deep Dive: Triggers

In the Android init language, triggers dictate when a set of commands (an Action) should be executed. Triggers are the event-driven mechanism that orchestrates the entire boot sequence and reacts to system state changes.

Boot Triggers

Boot triggers represent specific milestones in the Android boot process. They are hardcoded in the init binary and execute in a strict, predefined order.

The primary boot triggers, in order of execution, are:

  1. early-init: Executed immediately after init starts. Used for setting up the very basic kernel environment and initializing the SELinux environment.
  2. init: Used for mounting essential filesystems (like /tmp, /dev/pts) and creating basic directories.
  3. early-fs: Occurs just before the main filesystems are mounted.
  4. fs: The trigger where partitions like /system, /vendor, and /data are typically mounted.
  5. post-fs: Executed after the main filesystems are mounted. Used to configure SELinux contexts on the newly mounted filesystems.
  6. post-fs-data: Executed after /data is mounted and decrypted. This is when user-specific directories are created.
  7. boot: The final major boot trigger. At this point, the system is ready to start the main Android framework services (e.g., launching Zygote).
on boot
    # Network setup
    ifup lo
    hostname localhost
    domainname localdomain

Property Triggers

Property triggers fire dynamically when a specific Android system property changes to a defined value. This allows the system to react to events that happen after the initial boot sequence.

For example, a developer service might only be enabled if the build type is eng (engineering) or userdebug.

on property:ro.build.type=eng
    start console
    
on property:sys.boot_completed=1
    # Executed when the Android framework finishes booting
    start bootanim_stop

Property triggers can also evaluate multiple conditions using &&:

on property:sys.boot_completed=1 && property:ro.debuggable=1
    start my_debug_service

Action Ordering

When init parses the .rc files, it builds a queue of actions.

  • Boot Triggers: Added to the queue in the exact sequence dictated by the C++ init code.
  • Property Triggers: Evaluated iteratively. If multiple property triggers evaluate to true simultaneously, they are executed in the order they were parsed from the .rc files.

Understanding this ordering is critical when debugging boot issues. If a command in the fs trigger relies on a directory created in post-fs, it will fail because fs executes first.