在前面两篇博客中我们已经分析了system_server进程是如何被zogote进程一步一步fork出来的,并在ZogoteInit.MethodAndArgsCaller类的run方法中执行了SystemServer的main方法,如果你还不是很熟悉这个流程,那不妨先去看一下之前的博客SystemServer启动流程之SystemServer启动(二),本篇博客将带领大家详细的了解SystemServer的神奇。
我们直接进入SystemServer类的main方法。
(1)SystemServer.main()
源码:frameworks/base/services/java/com/android/server/SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
/* @SPRD: Create hporfile directory for hporfile. @{ */
String hprofile_path = android.os.Environment.getDataDirectory() + "/misc/hprofs/";
File dir = new File(hprofile_path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.w(TAG, "Path{" + hprofile_path + "} does not exist, and failed to create.");
} else {
Log.w(TAG, "Path{" + hprofile_path + "} does not exist, and success to create.");
try {
libcore.io.Libcore.os.chmod(hprofile_path, 0777);
} catch (Exception e) {
Log.w(TAG, "Failed to chmod(" + hprofile_path + "): " + e);
}
}
}
/* @} */
//创建SystemServer对象并调用其run方法
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
}
(2)SystemServer.run()
源码:frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it shortly.
//(1)调整系统时间
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
// In case the runtime switched since last boot (such as when
// the old runtime was removed in an OTA), set the system
// property so that it is in sync. We can't do this in
// libnativehelper's JniInvocation::Init code where we already
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
//(2)设置当前虚拟机的运行库路径
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Enable the sampling profiler.
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!
VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty();
// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
Environment.setUserRequired(true);
// Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true);
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Initialize native services.
//(3)装载libandroid_servers.so库并初始化native层的Service
System.loadLibrary("android_servers");
nativeInit();
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
//(4)初始化系统的Context
createSystemContext();
// Create the system service manager.
//(5)创建SystemServiceManager对象并将其添加到LocalServices中
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start services.
try {
//(6)启动系统中所有的Java Service
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
// Loop forever.
//(7)创建消息队列循环用于处理消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
通过以上分析其实main方法的主要作用是:
1、调整系统时间
2、设置属性persist.sys.dalvik.vm.lib.2的值为当前虚拟机的运行库路径
3、装载libandroid_servers.so库,初始化native层service
4、初始化系统Context
5、创建SystemServiceManager对象
6、调用startBootstrapServices(),startCoreServices(),startOtherServices()启动所有的Java服务
7、调用Looper.loop()创建消息队列循环
接下来我们将对以上的步骤进行详细分析。
(3)SystemServer.nativeInit()
这是一个native方法,其对应的native文件在\frameworks\base\services\core\jni中的com_android_server_SystemServer.cpp,我们进入该文件的android_server_SystemServer_nativeInit方法。
static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the sensor service
SensorService::instantiate();
}
}
这里的native服务只有SensorService,SensorService提供各种传感器服务。
(4)SystemServer.createSystemContext()
private Context mSystemContext;
//创建Context
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(true);
} else {
HardwareRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true);
return thread;
}
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
实际返回的是ContextImpl对象,并将其保存在mSystemContext变量中。
(5)new SystemServiceManager()
//这个类很重要,在后续创建Java世界的Service时都要使用到它
public class SystemServiceManager {
private final Context mContext;
public SystemServiceManager(Context context) {
mContext = context;
}
}
将上一步创建好的Context对象传入到SystemServiceManager构造器中,并创建SystemServiceManager对象mSystemServiceManager,同时将mSystemServiceManager添加到LocalServices中。
/**
* This class is used in a similar way as ServiceManager, except the services registered here
* are not Binder objects and are only available in the same process.
*
* Once all services are converted to the SystemService interface, this class can be absorbed
* into SystemServiceManager.
*
* {@hide}
*/
public final class LocalServices {
private LocalServices() {}
private static final ArrayMap, Object> sLocalServiceObjects =
new ArrayMap, Object>();
/**
* Returns a local service instance that implements the specified interface.
*
* @param type The type of service.
* @return The service object.
*/
@SuppressWarnings("unchecked")
public static T getService(Class type) {
synchronized (sLocalServiceObjects) {
return (T) sLocalServiceObjects.get(type);
}
}
/**
* Adds a service instance of the specified interface to the global registry of local services.
*/
public static void addService(Class type, T service) {
synchronized (sLocalServiceObjects) {
if (sLocalServiceObjects.containsKey(type)) {
throw new IllegalStateException("Overriding service registration");
}
sLocalServiceObjects.put(type, service);
}
}
}
(6)启动Java层所有的Service
创建Java Service由于涉及到三个方法,我们来单独分析。
我们首先来看一下startBootstrapServices这个方法, 这个方法主要是启动系统引导的Service。
private void startBootstrapServices() {
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
Installer installer = mSystemServiceManager.startService(Installer.class);
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Now that the power manager has been started, let the activity manager
// initialize power management features.
mActivityManagerService.initPowerManagement();
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
if (SystemProperties.get("persist.support.securetest").equals("1")){
Slog.i(TAG, "Security Service");
security = new SecurityService();
ServiceManager.addService(Context.SECURITY_SERVICE, security);
}
// We need the default display before we can initialize the package manager.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// Only run "core" apps if we're encrypting the device.
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// Start the package manager.
Slog.i(TAG, "Package Manager");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
Slog.i(TAG, "User Service");
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
// Initialize attribute cache used to cache resources from packages.
AttributeCache.init(mSystemContext);
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
}
这个方法中启动的都是系统中的核心服务,比如ActivityManagerService,PowerManagerService,PackageManagerService等,其实这里启动服务的不外乎就两种方式,我们对其单独分析。
1、通过SystemServiceManager.startService方式启动
还记得我们在之前的run方法中已经将SystemServiceManager对象创建出来了吗?这里直接调用其startService方法,我们看下其源码。
public class SystemServiceManager {
private final Context mContext;
// Services that should receive lifecycle events.
//用于保存新创建的服务,类型是ArrayList
private final ArrayList mServices = new ArrayList();
public SystemServiceManager(Context context) {
mContext = context;
}
//通过类名来启动服务
public SystemService startService(String className) {
final Class serviceClass;
try {
serviceClass = (Class)Class.forName(className);
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
throw new RuntimeException("Failed to create service " + className
+ ": service class not found, usually indicates that the caller should "
+ "have called PackageManager.hasSystemFeature() to check whether the "
+ "feature is available on this device before trying to start the "
+ "services that implement it", ex);
}
return startService(serviceClass);
}
//通过类的对象来启动服务
public T startService(Class serviceClass) {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
// 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 constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
// Register it.
//这里很重要,将获得的类加入到mServices的List中
mServices.add(service);
// Start it.
try {
//调用要启动服务的onStart方法
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;
}
}
以上就是SystemServiceManager比较重要的逻辑,其实就是将需要启动的服务通过startService方法反射后添加到ArrayList
这样看来,所有通过SystemServiceManager.startService方法添加的服务都需要继承于SystemService类,我们来看一下SystemService类。
/**
* The base class for services running in the system process. Override and implement
* the lifecycle event callback methods as needed.
*/
public abstract class SystemService {
private final Context mContext;
public SystemService(Context context) {
mContext = context;
}
/**
* Gets the system context.
*/
public final Context getContext() {
return mContext;
}
//......
/**
* Publish the service so it is accessible to other services and apps.
*/
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
//通过ServiceManager.addService添加服务
ServiceManager.addService(name, service, allowIsolated);
}
/**
* Get a binder service by its name.
*/
protected final IBinder getBinderService(String name) {
return ServiceManager.getService(name);
}
/**
* Publish the service so it is only accessible to the system process.
*/
protected final void publishLocalService(Class type, T service) {
//通过LocalServices.addService添加服务
LocalServices.addService(type, service);
}
/**
* Get a local service by interface.
*/
protected final T getLocalService(Class type) {
return LocalServices.getService(type);
}
private SystemServiceManager getManager() {
return LocalServices.getService(SystemServiceManager.class);
}
}
可以看出SystemService是一个抽象类,其主要的添加服务的方法是通过ServiceManager.addService或LocalServices.addService进行的,接下来我们在来看第二种启动服务的方式。
2、通过ServiceManager.addService()方法进行的,比如ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()),我们来看ServiceManager源码。
public final class ServiceManager {
private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
private static HashMap sCache = new HashMap();
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
/**
* Returns a reference to a service with the given name.
*
* @param name the name of the service to get
* @return a reference to the service, or null
if the service doesn't exist
*/
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
//这里是ServiceManager的addService方法
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
* @param allowIsolated set to true to allow isolated sandboxed processes
* to access this service
*/
//重载的addService方法
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
/**
* Retrieve an existing service called @a name from the
* service manager. Non-blocking.
*/
public static IBinder checkService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().checkService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in checkService", e);
return null;
}
}
/**
* Return a list of all currently running services.
*/
public static String[] listServices() throws RemoteException {
try {
return getIServiceManager().listServices();
} catch (RemoteException e) {
Log.e(TAG, "error in listServices", e);
return null;
}
}
/**
* This is only intended to be called when the process is first being brought
* up and bound by the activity manager. There is only one thread in the process
* at that time, so no locking is done.
*
* @param cache the cache of service references
* @hide
*/
public static void initServiceCache(Map cache) {
if (sCache.size() != 0) {
throw new IllegalStateException("setServiceCache may only be called once");
}
sCache.putAll(cache);
}
}
从以上代码可以发现两点:
(1)通过ServiceManager对象的addService方法添加的服务必须是一个Binder对象。
(2)无论是其addService还是getService等方法,其最终都是调用IServiceManager对象的相应方法。
我们在这里顺便看一下IServiceManager类。
/**
* Basic interface for finding and publishing system services.
*
* An implementation of this interface is usually published as the
* global context object, which can be retrieved via
* BinderNative.getContextObject(). An easy way to retrieve this
* is with the static method BnServiceManager.getDefault().
*
* @hide
*/
public interface IServiceManager extends IInterface
{
/**
* Retrieve an existing service called @a name from the
* service manager. Blocks for a few seconds waiting for it to be
* published if it does not already exist.
*/
public IBinder getService(String name) throws RemoteException;
/**
* Retrieve an existing service called @a name from the
* service manager. Non-blocking.
*/
public IBinder checkService(String name) throws RemoteException;
/**
* Place a new @a service called @a name into the service
* manager.
*/
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException;
/**
* Return a list of all currently running services.
*/
public String[] listServices() throws RemoteException;
/**
* Assign a permission controller to the service manager. After set, this
* interface is checked before any services are added.
*/
public void setPermissionController(IPermissionController controller)
throws RemoteException;
static final String descriptor = "android.os.IServiceManager";
int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
}
/**
* Base class for Binder interfaces. When defining a new interface,
* you must derive it from IInterface.
*/
public interface IInterface
{
/**
* Retrieve the Binder object associated with this interface.
* You must use this instead of a plain cast, so that proxy objects
* can return the correct result.
*/
public IBinder asBinder();
}
这是一个接口类型的类,根据其注释可以看出,它是公共服务的基础接口,其所有方法有待子类实现。
好啦其实绕了一大圈主要就是想说明在SystemServer中注册服务用的就是SystemServiceManager.startService()方法和ServiceManager.addService()方法。
接下来我们继续往下走,进入我们的startCoreServices方法,这个方法用于启动系统的核心服务。
/**
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
// Manages LEDs and display backlight.
mSystemServiceManager.startService(LightsService.class);
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
// Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Update after UsageStatsService is available, needed before performBootDexOpt.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
mSystemServiceManager.startService(WebViewUpdateService.class);
}
这里就不做过多解释了,紧接着就是进入了我们的最后一个启动服务的方法startOtherServices()。
private void startOtherServices() {
final Context context = mSystemContext;
AccountManagerService accountManager = null;
ContentService contentService = null;
VibratorService vibrator = null;
IAlarmManager alarm = null;
MountService mountService = null;
//......
accountManager = new AccountManagerService(context);
ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
mountService = new MountService(context);
ServiceManager.addService("mount", mountService);
//......
//这里需要重点关注
final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);
Watchdog.getInstance().start();
//启动系统UI
startSystemUi(context);
//......
}
这个方法有一千多行,基本都是启动各种服务等,在此我们就不一一深究了,但是在这里我想重点关注一下Watchdog这个类,这是一个监控服务的类其一旦发现某些服务有异常,它将做相应的处理。我准备在下篇博客中详细的讲解这个功能。
到这里基本上我们的StstemServer就分析完毕啦,我们总共花了三篇博客的内容来讲解了其启动流程,接下来我们用一张时序图来直观的表达其流程。
好啦,今天的SystemServer分析就到这里啦,接下来我们总结一下本篇博客的内容。
其实SystemServer.main方法不外乎主要就做了以下几件事情:
1、调整系统时间。
2、设置虚拟机运行库路径和装在so库并初始化native的服务。
3、初始化系统的Context和创建SystemServiceManager对象。
4、通过调用startBootstrapServices(),startCoreServices(),startOtherServices()启动所有的Java服务 。
5、调用Looper.loop()创建消息队列循环等待消息进行处理。