AOSP Framework & Internals
6 min read

hwservicemanager

Learn about hwservicemanager.

The Treble Boundary

Before Android 8.0, framework code and hardware drivers lived in a tangled monolith. Updating the Android OS often broke vendor implementations because they shared the same memory space and dependencies. Project Treble forced a strict architectural split between the system and the vendor partitions. This separation created a new communication problem. The framework still needed to talk to hardware components, but they were now isolated in different processes.

To bridge this gap, Android introduced a dedicated inter-process communication registry. Standard framework services already used the primary binder domain, but hardware services needed their own isolated channel. This requirement is exactly why hwservicemanager exists. The daemon acts as the central directory where hardware services announce themselves and framework clients look them up.

The following flowchart shows the separation of binder domains in modern Android. This visual helps clarify why two distinct service managers run simultaneously. Look for how standard apps route through servicemanager while hardware calls go through hwservicemanager.

This diagram illustrates the complete physical separation of the two registries. The system server must connect to hwservicemanager to reach the camera driver. These isolated domains ensure that a crash in a framework service does not bring down the hardware routing table.

Registering a Hardware Service

You might wonder how a camera or light sensor actually tells the system to start sending commands. When a vendor device boots, its hardware services start up as independent processes. These processes cannot simply wait for the framework to find them. They must actively advertise their presence to the system.

Vendor processes achieve this by registering themselves with hwservicemanager. They use a specific C++ API generated by the Hardware Interface Definition Language. The service creates an instance of its implementation and calls a registration method. Passing a recognizable name, usually "default", tells clients exactly what to look for.

Our code below initializes a new Light sensor service. It instantiates the sensor class and submits it to the registry. This guarantees the service will be ready when the framework requests it.

#include <android/hardware/light/2.0/ILight.h>

using android::hardware::light::V2_0::ILight;
using android::hardware::light::V2_0::implementation::Light;

int main() {
    android::sp<ILight> service = new Light();
    
    // Announce presence to hwservicemanager
    android::status_t status = service->registerAsService("default");
    
    android::hardware::joinRpcThreadpool();
    return 0;
}

Calling registerAsService blocks until the manager acknowledges the registration. Once successful, the thread joins the RPC pool and waits for incoming requests. A successful registration effectively bridges the gap between the isolated vendor process and the central system registry.

Common Mistake: Forgetting to start the thread pool leaves the service registered but entirely unresponsive to client calls.

Discovering the Service

Now the hardware is ready, but the framework remains unaware of its existence. A system component like the Display service needs to adjust screen brightness. The display code does not know the memory address or the process ID of the Light sensor. Instead, the system only knows that a Light interface should exist somewhere on the device.

The framework client asks hwservicemanager for help finding it. Calling the static getService method on the generated interface requires passing the same "default" name used during registration.

A snippet like the one below fetches the remote proxy object. It asks the manager for a specific name and receives a callable interface. You can expect a non-null pointer if the hardware is running properly.

android::sp<ILight> light = ILight::getService("default");

if (light != nullptr) {
    light->setLight(...);
}

Visualizing this handshake clarifies the exact order of operations when a new hardware module starts up. The sequence diagram below shows how hwservicemanager acts as the middleman connecting the vendor process to the framework client. Look for the exact moment the client receives the proxy.

Looking up the name in the internal registry allows the service manager to return a binder proxy object. After receiving this proxy, the client uses it just like a local object. Every method call gets serialized and executed in the vendor process. This discovery mechanism keeps the framework completely decoupled from the hardware implementation.

Enforcing the VINTF Manifest

Many developers assume that hwservicemanager blindly accepts any service that attempts to register. The standard servicemanager allows dynamic registrations as long as SELinux policies permit them. However, hardware services carry strict compatibility requirements. If a vendor registers an unexpected module version, the framework might crash when trying to interact with an incompatible interface.

To prevent this, hwservicemanager enforces a strict access control policy using the Vendor Interface Object manifest. This manifest is an XML file baked into the vendor partition. The document explicitly declares every hardware module, version, and transport mechanism the device supports.

An XML snippet like the one below defines a valid sensor configuration. It establishes the exact version and transport method allowed on this device. When parsed, this tells the system exactly which calls are legally permitted.

<hal format="hidl">
    <name>android.hardware.light</name>
    <transport>hwbinder</transport>
    <version>2.0</version>
    <interface>
        <name>ILight</name>
        <instance>default</instance>
    </interface>
</hal>

Before accepting a registration, hwservicemanager reads this manifest. When a module tries to register but is missing from the XML, the service manager outright rejects the request. This strict enforcement guarantees that the framework knows exactly what hardware capabilities exist at boot time. Eliminating runtime surprises ensures the device passes Treble compliance testing.

Warning: Modifying vendor code to start a new service without also adding it to the manifest is a guaranteed way to cause a silent boot failure. The service will crash immediately upon calling the registration method.

The architectural split introduced by Treble made hwservicemanager an indispensable part of modern Android. By providing a stable and verifiable registry, the daemon manages all hardware interactions safely. It ensures that processes declare themselves properly and that the framework can discover them without knowing physical addresses.

You have seen how the system handles HIDL interfaces. The natural next question is how Android accommodates the newer generation of AIDL hardware services. Those newer interfaces introduce a completely different set of rules for service discovery.