SystemServer启动流程之SystemServer分析(三)

1、概述

在前面两篇博客中我们已经分析了system_server进程是如何被zogote进程一步一步fork出来的,并在ZogoteInit.MethodAndArgsCaller类的run方法中执行了SystemServer的main方法,如果你还不是很熟悉这个流程,那不妨先去看一下之前的博客SystemServer启动流程之SystemServer启动(二),本篇博客将带领大家详细的了解SystemServer的神奇。

2、源码分析

我们直接进入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集合中(其类型是SystemService),并调用该服务的onStart方法。
这样看来,所有通过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这个类,这是一个监控服务的类其一旦发现某些服务有异常,它将做相应的处理。我准备在下篇博客中详细的讲解这个功能。

3、SystemServer启动时序图

到这里基本上我们的StstemServer就分析完毕啦,我们总共花了三篇博客的内容来讲解了其启动流程,接下来我们用一张时序图来直观的表达其流程。
SystemServer启动流程之SystemServer分析(三)_第1张图片

好啦,今天的SystemServer分析就到这里啦,接下来我们总结一下本篇博客的内容。

4、总结

其实SystemServer.main方法不外乎主要就做了以下几件事情:

1、调整系统时间。

2、设置虚拟机运行库路径和装在so库并初始化native的服务。

3、初始化系统的Context和创建SystemServiceManager对象。

4、通过调用startBootstrapServices(),startCoreServices(),startOtherServices()启动所有的Java服务 。

5、调用Looper.loop()创建消息队列循环等待消息进行处理。

你可能感兴趣的:(Android底层分析)