How to create and start Android SystemServer (based on Android13)
Introduction to SystemServer
Android System Server is the core component of the Android framework. It runs in the system_server process and has system permissions. It plays an important role in the Android system, providing service management and communication.
system 548 415 1 06:23:21 ? 00:11:21 system_server
The location of SystemServer in the Android system is as follows
SystemServer service provider serviceManager
SystemServer uses ServiceManager to provide services, similar to keystore, ServiceManager is a native service responsible for service management in SystemServer. SystemServer communicates with ServiceManager through binder.
ServiceManager is started by servicemanager.rc, and related implementations are in the aidl interface provided by ServiceManager.
//frameworks/native/cmds/servicemanager/
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
onrestart restart keystore
onrestart restart gatekeeperd
onrestart restart thermalservice
writepid /dev/cpuset/system-background/tasks
shutdown critical
These interfaces are located frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
, mainly including addService、getService、checkService
and some permission checks.
//frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
interface IServiceManager {
/*
* Must update values in IServiceManager.h
*/
/* Allows services to dump sections according to priorities. */
const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
/**
* Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the
* same priority as NORMAL priority but the services are not called with dump priority
* arguments.
*/
const int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3;
const int DUMP_FLAG_PRIORITY_ALL = 15;
// DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
// | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
/* Allows services to dump sections in protobuf format. */
const int DUMP_FLAG_PROTO = 1 << 4;
/**
* Retrieve an existing service called @a name from the
* service manager.
*
* This is the same as checkService (returns immediately) but
* exists for legacy purposes.
*
* Returns null if the service does not exist.
*/
@UnsupportedAppUsage
@nullable IBinder getService(@utf8InCpp String name);
/**
* Retrieve an existing service called @a name from the service
* manager. Non-blocking. Returns null if the service does not
* exist.
*/
@UnsupportedAppUsage
@nullable IBinder checkService(@utf8InCpp String name);
/**
* Place a new @a service called @a name into the service
* manager.
*/
void addService(@utf8InCpp String name, IBinder service,
boolean allowIsolated, int dumpPriority);
/**
* Return a list of all currently running services.
*/
@utf8InCpp String[] listServices(int dumpPriority);
/**
* Request a callback when a service is registered.
*/
void registerForNotifications(@utf8InCpp String name, IServiceCallback callback);
/**
* Unregisters all requests for notifications for a specific callback.
*/
void unregisterForNotifications(@utf8InCpp String name, IServiceCallback callback);
/**
* Returns whether a given interface is declared on the device, even if it
* is not started yet. For instance, this could be a service declared in the VINTF
* manifest.
*/
boolean isDeclared(@utf8InCpp String name);
/**
* Request a callback when the number of clients of the service changes.
* Used by LazyServiceRegistrar to dynamically stop services that have no clients.
*/
void registerClientCallback(@utf8InCpp String name, IBinder service, IClientCallback callback);
/**
* Attempt to unregister and remove a service. Will fail if the service is still in use.
*/
void tryUnregisterService(@utf8InCpp String name, IBinder service);
}
After the servicemanager starts, it will register a special service, the service name is "manager", and the dumpsys -l
service named "manager" can be found through the command.
//frameworks/native/cmds/servicemanager/main.cpp
sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
LOG(ERROR) << "Could not self register servicemanager";
}
Several ways to create a Service in a native framework
Method 1 ServiceManager.addService
ServiceManager.addService
It is the earliest service creation method, and the function prototype is
public static void addService(String name, IBinder service) {
addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}
In early Android versions, ServiceManager.addService
it was the earliest way to create a service. Its function prototype is ServiceManager.addService
, because it exists in the early version, so it can be used without too many restrictions, and it can be used even in android_app.
方式2 SystemServiceManager.startService
SystemServiceManager.startService
There are multiple override methods, and the interface is defined as follows:
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
The SystemService class is located frameworks/base/services/core/java/com/android/server/SystemService.java
and finally packaged into service.jar. However, due to the annotations added to SystemService, directly dependent on services.jar cannot access this class.
We can use SystemService in two ways:
- In
frameworks/base/services
the internal source code, you can directly access SystemService. - Declare the module as in Android.bp
sdk_version: "system_server_current"
, you can also use SystemService.
In addition, SystemService can also be accessed by relying on the static library services.core, for example, Apex service uses this method.