The opening
This article uses Android – 11.0.0_R25 as the basic analysis
We analyze how the SystemServer process is started, today this article, we will analyze the SystemServer process started to do what
main
As we saw in the previous chapter, Zygote forks a child process and eventually calls systemServer. main. SystemServer source code in the frameworks/base/services/Java/com/android/server/SystemServer. In Java, we came to see as a what
public static void main(String[] args) {
new SystemServer().run();
}
Copy the code
A constructor
Very simple, just new a SystemServer object, then call its run method, let’s look at the constructor
public SystemServer(a) {
// Factory modemFactoryTestMode = FactoryTest.getMode(); .// Record the startup information
// Record whether a restart was experienced
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}
Copy the code
The factory pattern
First, we get the factory pattern level from the system properties, which are three:
FACTORY_TEST_OFF
: Normal modeFACTORY_TEST_LOW_LEVEL
: Low-level factory mode, in which many services do not startFACTORY_TEST_HIGH_LEVEL
: High-level factory mode, this mode is basically the same as normal mode, with slight differences
They are defined in the frameworks/base/core/Java/android/OS/FactoryTest. In Java
run
The run method is then executed
private void run(a) {...// Record the startup information
// If no time zone is set, set the time zone to GMT
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
Slog.w(TAG, "Timezone not set; setting to GMT.");
SystemProperties.set("persist.sys.timezone"."GMT");
}
// Set the region and language
if(! SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language"."");
SystemProperties.set("persist.sys.country"."");
SystemProperties.set("persist.sys.localevar"."");
}
// Warn when a Binder transaction is blocked
Binder.setWarnOnBlocking(true);
/ / PackageManager relatedPackageItemInfo.forceSafeLabels(); .// Set the virtual library file libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Clear the maximum memory growth limit for the VIRTUAL machine to obtain more memory
VMRuntime.getRuntime().clearGrowthLimit();
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty();
Before accessing environment variables, you need to explicitly specify the user
Environment.setUserRequired(true);
// Set the flag to handle BadParcelableException conservatively and not throw an exception
BaseBundle.setShouldDefuse(true);
// Set exception tracing
Parcel.setStackTraceParceling(true);
// Ensure that Binder call priority is always foreground priority
BinderInternal.disableBackgroundScheduling(true);
// Set the maximum number of Binder thread pools
BinderInternal.setMaxThreads(sMaxBinderThreads);
// Set the process priority to the foreground process
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// Prepare with the current thread as MainLooper
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
SystemServiceRegistry.sEnableServiceNotFoundWtf = true;
// Load the android_Servers. so library
System.loadLibrary("android_servers");
// Mark the process as heapable
initZygoteChildHeapProfiling();
//Debug option - start a thread to detect FD leaks
if (Build.IS_DEBUGGABLE) {
spawnFdLeakCheckThread();
}
// Check whether the last shutdown failed
performPendingShutdown();
// Initialize the System Context
createSystemContext();
// Create and set some modules that are required for each process to start (TelephonyServiceManager, StatsServiceManager)
ActivityThread.initializeMainlineModules();
// Create SystemServiceManager (manage all system Services)
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
// Use SystemServiceManager as a local process Service
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for the initialization taskSystemServerInitThreadPool.start(); .// Set the default exception handlerRuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf); .// Start the boot service
startBootstrapServices(t);
// Start the core service
startCoreServices(t);
// Start other servicesstartOtherServices(t); .// Initialize vm policies in strict mode
StrictMode.initVmDefaults(null); .// Enter the Looper loop and wait for Handler events
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Copy the code
As you can see, the run method mainly does the following
- Check and set various parameters handler
- create
SystemContext
- create
SystemServiceManager
- Start the service
Looper
cycle
The SystemContext creation step is done by ContextImpl, which will be examined in detail later, as will Looper, and we will focus on starting the service
Start the service
Starting a service is a three-step process, starting the boot service, starting the core service, and finally starting the other services, starting with the boot service
Because there are so many services launched, we will cover only those we are familiar with
startBootstrapServices
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {.../ / watchdog
finalWatchdog watchdog = Watchdog.getInstance(); watchdog.start(); .final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
// Read the system configurationSystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG); .//Installer service (actually communicating with installd across processes)Installer installer = mSystemServiceManager.startService(Installer.class); .// create ATMS & AMSActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); .// The power management service needs to be started earlier because other services depend on itmPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); . mActivityManagerService.initPowerManagement(); .// Light servicemSystemServiceManager.startService(LightsService.class); .// Display management servicesmDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); .100 / / stagemSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); ./ / create the PMS
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); }finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
// Capture the dex load behavior
SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);
// Whether to start for the first time
mFirstBoot = mPackageManagerService.isFirstBoot();
/ / get the PMSmPackageManager = mSystemContext.getPackageManager(); .// User management servicesmSystemServiceManager.startService(UserManagerService.LifeCycle.class); .// Initialize the property cacheAttributeCache.init(mSystemContext); .// Register various system servicesmActivityManagerService.setSystemProcess(); .// Use AMS to complete the watchdog setup and listen for a restartwatchdog.init(mSystemContext, mActivityManagerService); .// Set the scheduling policymDisplayManagerService.setupSchedulerPolicies(); .// Start sensor service in a separate threadmSensorServiceStart = SystemServerInitThreadPool.submit(() -> { TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog(); traceLog.traceBegin(START_SENSOR_SERVICE); startSensorService(); traceLog.traceEnd(); }, START_SENSOR_SERVICE); . }Copy the code
startCoreServices
private void startCoreServices(@NonNull TimingsTraceAndSlog t) {...// Battery power service depends on LightsServicemSystemServiceManager.startService(BatteryService.class); .// Apply the statistics servicemSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); . }Copy the code
startOtherServices
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {...//AccountManagerService - Account managementmSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS); .//ContentService - ContentServicemSystemServiceManager.startService(CONTENT_SERVICE_CLASS); ./ / load SettingProvidermActivityManagerService.installSystemProviders(); .//DropBox log servicemSystemServiceManager.startService(DropBoxManagerService.class); .// Vibration service
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator); .// Clock/alarm clock service
mSystemServiceManager.startService(new AlarmManagerService(context));
// Enter the service
inputManager = newInputManagerService(context); .// Wait for sensor service to be ready
ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
mSensorServiceStart = null;
/ / start WindowManagerServicewm = WindowManagerService.main(context, inputManager, ! mFirstBoot, mOnlyCore,new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); . mActivityManagerService.setWindowManager(wm); . wm.onInitReady(); .//HIDL servicesSystemServerInitThreadPool.submit(() -> { startHidlServices(); }, START_HIDL_SERVICES); .// Associate the WMS to start the input serviceinputManager.setWindowManagerCallbacks(wm.getInputManagerCallback()); inputManager.start(); . mDisplayManagerService.windowManagerAndInputReady(); .// Bluetooth enabled and not low level factory mode, enable Bluetooth service
if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
...
} else if(! context.getPackageManager().hasSystemFeature (PackageManager.FEATURE_BLUETOOTH)) { ... }else{ mSystemServiceManager.startService(BluetoothService.class); }...// Input method/barrier-free service
if(mFactoryTestMode ! = FactoryTest.FACTORY_TEST_LOW_LEVEL) {if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) {
mSystemServiceManager.startService(
MultiClientInputMethodManagerService.Lifecycle.class);
} else {
mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class);
}
mSystemServiceManager.startService(ACCESSIBILITY_MANAGER_SERVICE_CLASS);
}
wm.displayReady();
// Store related services
if(mFactoryTestMode ! = FactoryTest.FACTORY_TEST_LOW_LEVEL) {if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
mSystemServiceManager.startService(STORAGE_MANAGER_SERVICE_CLASS);
storageManager = IStorageManager.Stub.asInterface(
ServiceManager.getService("mount")); mSystemServiceManager.startService(STORAGE_STATS_SERVICE_CLASS); }}//UIMode service (night mode, driving mode, etc.)mSystemServiceManager.startService(UiModeManagerService.class); .// Clear the disk to release disk space
mPackageManagerService.performFstrimIfNeeded();
if(mFactoryTestMode ! = FactoryTest.FACTORY_TEST_LOW_LEVEL) { ...final booleanhasPdb = ! SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals(""); .if (hasPdb || OemLockService.isHalPresent()) {
/ / OEM lock servicemSystemServiceManager.startService(OemLockService.class); }...if(! isWatch) {// Status bar management services
statusBar = new StatusBarManagerService(context);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
}
// Network related services
ConnectivityModuleConnector.getInstance().init(context);
NetworkStackClient.getInstance().init();
networkManagement = NetworkManagementService.create(context);
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
ipSecService = IpSecService.create(context, networkManagement);
ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
// Text services
mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
mSystemServiceManager
.startService(TextClassificationManagerService.Lifecycle.class);
// Network related services
mSystemServiceManager.startService(NetworkScoreService.Lifecycle.class);
networkStats = NetworkStatsService.create(context, networkManagement);
ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
networkManagement);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI)) {
mSystemServiceManager.startServiceFromJar(
WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
mSystemServiceManager.startServiceFromJar(
WIFI_SCANNING_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_RTT)) {
mSystemServiceManager.startServiceFromJar(
WIFI_RTT_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_AWARE)) {
mSystemServiceManager.startServiceFromJar(
WIFI_AWARE_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_DIRECT)) {
mSystemServiceManager.startServiceFromJar(
WIFI_P2P_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
}
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_LOWPAN)) {
mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
}
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
}
connectivity = new ConnectivityService(
context, networkManagement, networkStats, networkPolicy);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL); networkPolicy.bindConnectivityManager(connectivity); .// System update service
ServiceManager.addService(Context.SYSTEM_UPDATE_SERVICE,
new SystemUpdateManagerService(context));
ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
new UpdateLockService(context));
// Notification servicemSystemServiceManager.startService(NotificationManagerService.class); SystemNotificationChannels.removeDeprecated(context); SystemNotificationChannels.createAll(context); notification = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); .// Location servicesmSystemServiceManager.startService(LocationManagerService.Lifecycle.class); .// Wallpaper service
if (context.getResources().getBoolean(R.bool.config_enableWallpaperService)) {
mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
} else{... }// Audio service
if(! isArc) { mSystemServiceManager.startService(AudioService.Lifecycle.class); }else {
String className = context.getResources()
.getString(R.string.config_deviceSpecificAudioService);
mSystemServiceManager.startService(className + "$Lifecycle"); }.../ / ADB service
mSystemServiceManager.startService(ADB_SERVICE_CLASS);
/ / USB service
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
|| mPackageManager.hasSystemFeature(
PackageManager.FEATURE_USB_ACCESSORY)
|| isEmulator) {
mSystemServiceManager.startService(USB_SERVICE_CLASS);
}
// Widget service
if(mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS) || context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) { mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS); }...// New in Android10 for reporting information from runtime modules
ServiceManager.addService("runtime".newRuntimeService(context)); .//App background Dex optimizationBackgroundDexOptService.schedule(context); . }...// Camera service
if(! disableCameraService) { mSystemServiceManager.startService(CameraServiceProxy.class); }// Enter safe mode
if (safeMode) {
mActivityManagerService.enterSafeMode();
}
// SMS servicemmsService = mSystemServiceManager.startService(MmsServiceBroker.class); .// Clipboard servicemSystemServiceManager.startService(ClipboardService.class); .// Call the systemReady method of each major service
vibrator.systemReady();
lockSettings.systemReady();
480 / / stage
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_LOCK_SETTINGS_READY);
500 / / stagemSystemServiceManager.startBootPhase(t, SystemService.PHASE_SYSTEM_SERVICES_READY); wm.systemReady(); .// Manually update Context Configuration
final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
DisplayMetrics metrics = new DisplayMetrics();
context.getDisplay().getMetrics(metrics);
context.getResources().updateConfiguration(config, metrics);
final Theme systemTheme = context.getTheme();
if(systemTheme.getChangingConfigurations() ! =0) { systemTheme.rebase(); } mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService()); . mPackageManagerService.systemReady(); mDisplayManagerService.systemReady(safeMode, mOnlyCore); mSystemServiceManager.setSafeMode(safeMode);520 / / stagemSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); .// Finally run ams.systemReady
mActivityManagerService.systemReady(() -> {
550 / / stagemSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY); .600 / / stagemSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); . }, t); }Copy the code
The startup of the service is done in phases, from 0-100-480-500-520-550-600-1000, with the final phase 1000, entered after AMS calls the finishBooting method
As you can see, there are so many services launched that it is impossible to see all of them. The most important ones are: Before we look at ActivityManagerService, WindowManagerService, PackageManagerService, and InputManagerService, let’s look at how services start
SystemServiceManager
Most of the services is through SystemServiceManager launched, its source code path for frameworks/base/services/core/Java/com/android/server/SystemServiceManager. Java
startService
Let’s look at the start service method in this class
There are three methods in this class to start Serivce:
public SystemService startService(String className)
public SystemService startServiceFromJar(String className, String path)
public <T extends SystemService> T startService(Class<T> serviceClass)
public void startService(@NonNull final SystemService service)
In fact, it always ends up calling the last method
Start with the startService method, which takes a String
public SystemService startService(String className) {
final Class<SystemService> serviceClass = loadClassFromLoader(className,
this.getClass().getClassLoader());
return startService(serviceClass);
}
Copy the code
private static Class<SystemService> loadClassFromLoader(String className, ClassLoader classLoader) {
try {
return (Class<SystemService>) Class.forName(className, true, classLoader);
} catch(ClassNotFoundException ex) { ... }}Copy the code
In effect, the Class name is reflected and the startService method is called with Class as an argument
StartServiceFromJar is actually the same, but the JAR is loaded through the PathClassLoader first
public SystemService startServiceFromJar(String className, String path) {
PathClassLoader pathClassLoader = mLoadedPaths.get(path);
if (pathClassLoader == null) {
// NB: the parent class loader should always be the system server class loader.
// Changing it has implications that require discussion with the mainline team.
pathClassLoader = new PathClassLoader(path, this.getClass().getClassLoader());
mLoadedPaths.put(path, pathClassLoader);
}
final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader);
return startService(serviceClass);
}
Copy the code
Next, let’s look at the startService method with a Class parameter
public <T extends SystemService> T startService(Class<T> serviceClass) {
final String name = serviceClass.getName();
// Create the service.
if(! SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (...) {
...
}
startService(service);
return service;
}
Copy the code
This method only accepts subclasses of SystemService. At the beginning of the method, isAssignableFrom is used as a type check to avoid subclasses of SystemService obtained by String reflection
The logic is simple: reflect the instantiated object and call another overloaded method that takes the SystemService object as an argument
public void startService(@NonNull final SystemService service) {
mServices.add(service);
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex); }}Copy the code
This method adds the SystemService object to a List and calls its onStart method to tell SystemService to handle startup itself
startBootPhase
Because services are dependent on each other, Android divides the startup of a service into eight phases: 0-100-480-500-520-550-600-1000, and the startBootPhase method is used to inform each service which phase it is in
public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
service.onBootPhase(mCurrentPhase);
}
if(phase == SystemService.PHASE_BOOT_COMPLETED) { SystemServerInitThreadPool.shutdown(); }}Copy the code
The onBootPhase method of all systemServices in the Service List is called each time a phase is completed, notifying SystemService of the phase transition. When the phase reaches 1000 (PHASE_BOOT_COMPLETED), Represents all of the services have been ready, closed SystemServerInitThreadPool thread pool
ServiceManager
After the service is created, invokes the ServiceManager. The addService method to add service, use these services to other places
AddService has three overloads and ends up calling:
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e); }}Copy the code
private static IServiceManager getIServiceManager(a) {
if(sServiceManager ! =null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
Copy the code
public static IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// ServiceManager is never local
return new ServiceManagerProxy(obj);
}
Copy the code
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
mServiceManager = IServiceManager.Stub.asInterface(remote);
}
public IBinder asBinder(a) {
returnmRemote; }...public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
throws RemoteException { mServiceManager.addService(name, service, allowIsolated, dumpPriority); }...private IBinder mRemote;
private IServiceManager mServiceManager;
}
Copy the code
The ServiceManager is actually a separate process named ServiceManager, which manages all services using the Binder IPC mechanism. We call the addService method which actually calls the Binder Proxy method. He writes a message to /dev/binder, which is received in the Servicemanager process and processes the request
The Binder mechanism will be examined later
Finally call the frameworks/native/CMDS servicemanager/servicemanager. The addService function of CPP
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
auto ctx = mAccess->getCallingContext(a); .// Add a service
auto entry = mNameToService.emplace(name, Service {
.binder = binder,
.allowIsolated = allowIsolated,
.dumpPriority = dumpPriority,
.debugPid = ctx.debugPid,
});
auto it = mNameToRegistrationCallback.find(name);
if(it ! = mNameToRegistrationCallback.end()) {
for (const sp<IServiceCallback>& cb : it->second) {
entry.first->second.guaranteeClient = true;
// permission checked in registerForNotifications
cb->onRegistration(name, binder); }}return Status::ok(a); }Copy the code
As you can see, a Service structure is eventually constructed from the Service name and the passed binder object and stored in the mNameToService Map for later use
About the process
Most services started by SystemServer run in the SystemServer process, but there are some exceptions
The Installer service, for example, forks an Installd process from the init process
Here is its rc file, frameworks/native/CMDS installd/installd. Rc
service installd /system/bin/installd
class main
...
Copy the code
The Installer of Start in the SystemServer process is connected to the Installd process by binder
Source path frameworks/base/services/core/Java/com/android/server/PM/Installer. Java
@Override
public void onStart(a) {
if (mIsolated) {
mInstalld = null;
} else{ connect(); }}private void connect(a) {
IBinder binder = ServiceManager.getService("installd");
if(binder ! =null) {
try {
binder.linkToDeath(new DeathRecipient() {
@Override
public void binderDied(a) {
Slog.w(TAG, "installd died; reconnecting"); connect(); }},0);
} catch (RemoteException e) {
binder = null; }}if(binder ! =null) {
mInstalld = IInstalld.Stub.asInterface(binder);
try {
invalidateMounts();
} catch (InstallerException ignored) {
}
} else {
Slog.w(TAG, "installd not found; trying again"); BackgroundThread.getHandler().postDelayed(() -> { connect(); }, DateUtils.SECOND_IN_MILLIS); }}Copy the code
The end of the
SystemServer started a number of services and added them to the ServiceManager, from which we derived the Binder mechanism, which we begin to examine in the next chapter