Jimmy Chen

A Programmer

(原创)Android SystemServiceManager分析

1. SystemServiceManger启动

分析过SystemServer的朋友应该都有记忆,SystemServiceManager就是在SystemServer中启动的,下面是SystemServiceManager的启动代码:

[SystemServer.java]
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

这里直接通过new一个SystemServiceManager对象,然后将新new的对象保存到mSystemServiceManager中,以备后用。

  SystemServiceManager的代码如下:

public SystemServiceManager(Context context) {
    mContext = context;
}

这里只要将context保存到mContext中即可,现在SystemServiceManager就初始化完毕了。

2. SystemServiceManager代码分析

2.1 SystemServiceManager中的startService函数

/**
 * Starts a service by class name.
 *
 * @return The service instance.
 */
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
    // SystemrService类的class对象
    final Class<SystemService> serviceClass;
    try {
        // 通过Class.forName,传入String型类名,得到对应类名的class对象
        serviceClass = (Class<SystemService>)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);
    }
    // 调用另一个startService重载函数
    return startService(serviceClass);
}

/**
 * Creates and starts a system service. The class must be a subclass of
 * {@link com.android.server.SystemService}.
 *
 * @param serviceClass A Java class that implements the SystemService interface.
 * @return The service instance, never null.
 * @throws RuntimeException if the service fails to start.
 */
@SuppressWarnings("unchecked")
// 模板类函数,其中serviceClass必须是SystemService的子类
public <T extends SystemService> T startService(Class<T> serviceClass) {
    final String name = serviceClass.getName();
    Slog.i(TAG, "Starting " + name);

    // Create the service.
    // 再次确认serviceClass是SystemService的子类
    if (!SystemService.class.isAssignableFrom(serviceClass)) {
        throw new RuntimeException("Failed to create " + name
                + ": service must extend " + SystemService.class.getName());
    }
    final T service;
    try {
        // 获取service的构造函数
        Constructor<T> constructor = serviceClass.getConstructor(Context.class);
        // 创建service对象
        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.
    // 将service添加到mServices ArrayList中
    mServices.add(service);

    // Start it.
    try {
        // 启动service
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + name
                + ": onStart threw an exception", ex);
    }
    return service;
}

2.2 SystemServiceManager中的startBootPhase函数

/**
 * Starts the specified boot phase for all system services that have been started up to
 * this point.
 *
 * @param phase The boot phase to start.
 */
public void startBootPhase(final int phase) {
    if (phase <= mCurrentPhase) {
        throw new IllegalArgumentException("Next phase must be larger than previous");
    }
    mCurrentPhase = phase;

    Slog.i(TAG, "Starting phase " + mCurrentPhase);

    // 轮询mServices中所有的service
    final int serviceLen = mServices.size();
    for (int i = 0; i < serviceLen; i++) {
        final SystemService service = mServices.get(i);
        try {
            /// M: Service operation time log @{
            long startTime = 0;
            if (!IS_USER_BUILD) startTime = SystemClock.elapsedRealtime();
            /// @}

            // 调用service的onBootPhase方法
            service.onBootPhase(mCurrentPhase);

            /// M: Service operation time log @{
            if (!IS_USER_BUILD) {
                checkTime(startTime, "Phase " + mCurrentPhase, service.getClass().getName());
            }
            /// @}
        } catch (Exception ex) {
            throw new RuntimeException("Failed to boot service "
                    + service.getClass().getName()
                    + ": onBootPhase threw an exception during phase "
                    + mCurrentPhase, ex);
        }
    }
}

  startBootPhase也比较简单,因为有些service的启动需要以来其他的service,所以Systemserver会将设备启动分成几个阶段,每个阶段启动不同的service,而这些就是由startBootPhase这个方法来实现的。如果检测到当前的phase达到service的设定值,service就会完成相应的工作。下面是BatteryService的onBootPhase方法,可以知道当设备启动到PHASE_ACTIVITY_MANAGER_READY,该方法就会调用执行相应的操作。

public void onBootPhase(int phase) {
    if (phase == PHASE_ACTIVITY_MANAGER_READY) {
        // check our power situation now that it is safe to display the shutdown dialog.
        synchronized (mLock) {
            mBootCompleted = true;
            ContentObserver obs = new ContentObserver(mHandler) {
                @Override
                public void onChange(boolean selfChange) {
                    synchronized (mLock) {
                        updateBatteryWarningLevelLocked();
                    }
                }
            };
            final ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
                    false, obs, UserHandle.USER_ALL);
            updateBatteryWarningLevelLocked();
        }
    }
}

2.3 SystemServiceManager中剩余关于user的函数

  SystemServiceManager中剩余一下关于特定user的函数,具体的使用场景在SystemService.java中有描述,大家可以看下面代码中的注释,简单明了。

/**
 * Called when switching to a different foreground user, for system services that have
 * special behavior for whichever user is currently in the foreground.  This is called
 * before any application processes are aware of the new user.
 * @param userHandle The identifier of the user.
 */
public void onSwitchUser(int userHandle) {}

/**
 * Called when an existing user is stopping, for system services to finalize any per-user
 * state they maintain for running users.  This is called prior to sending the SHUTDOWN
 * broadcast to the user; it is a good place to stop making use of any resources of that
 * user (such as binding to a service running in the user).
 * @param userHandle The identifier of the user.
 */
public void onStopUser(int userHandle) {}

/**
 * Called when an existing user is stopping, for system services to finalize any per-user
 * state they maintain for running users.  This is called after all application process
 * teardown of the user is complete.
 * @param userHandle The identifier of the user.
 */
public void onCleanupUser(int userHandle) {}

3. 看看SystemService的内容

  系统中存在部分service是systemservice的子类,所以就顺便看看Systemservice的代码都有哪些:

public abstract class SystemService {
    // 列出设备启动的各个阶段
    /*
     * Boot Phases
     */
    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?

    /**
     * After receiving this boot phase, services can obtain lock settings data.
     */
    public static final int PHASE_LOCK_SETTINGS_READY = 480;

    /**
     * After receiving this boot phase, services can safely call into core system services
     * such as the PowerManager or PackageManager.
     */
    public static final int PHASE_SYSTEM_SERVICES_READY = 500;

    /**
     * After receiving this boot phase, services can broadcast Intents.
     */
    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

    /**
     * After receiving this boot phase, services can start/bind to third party apps.
     * Apps will be able to make Binder calls into services at this point.
     */
    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

    /**
     * After receiving this boot phase, services can allow user interaction with the device.
     * This phase occurs when boot has completed and the home application has started.
     * System services may prefer to listen to this phase rather than registering a
     * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
     */
    public static final int PHASE_BOOT_COMPLETED = 1000;

    private final Context mContext;

    /**
     * Initializes the system service.
     * 
     * Subclasses must define a single argument constructor that accepts the context
     * and passes it to super.
     * 
     *
     * @param context The system server context.
     */
    // systemservice的构造函数
    public SystemService(Context context) {
        mContext = context;
    }

    /**
     * Gets the system context.
     */
    public final Context getContext() {
        return mContext;
    }

    /**
     * Returns true if the system is running in safe mode.
     * TODO: we should define in which phase this becomes valid
     */
    public final boolean isSafeMode() {
        return getManager().isSafeMode();
    }

    /**
     * Called when the dependencies listed in the @Service class-annotation are available
     * and after the chosen start phase.
     * When this method returns, the service should be published.
     */
    public abstract void onStart();

    /**
     * Called on each phase of the boot process. Phases before the service's start phase
     * (as defined in the @Service annotation) are never received.
     *
     * @param phase The current boot phase.
     */
    public void onBootPhase(int phase) {}

    /**
     * Called when a new user is starting, for system services to initialize any per-user
     * state they maintain for running users.
     * @param userHandle The identifier of the user.
     */
    public void onStartUser(int userHandle) {}

    /**
     * Called when switching to a different foreground user, for system services that have
     * special behavior for whichever user is currently in the foreground.  This is called
     * before any application processes are aware of the new user.
     * @param userHandle The identifier of the user.
     */
    public void onSwitchUser(int userHandle) {}

    /**
     * Called when an existing user is stopping, for system services to finalize any per-user
     * state they maintain for running users.  This is called prior to sending the SHUTDOWN
     * broadcast to the user; it is a good place to stop making use of any resources of that
     * user (such as binding to a service running in the user).
     * @param userHandle The identifier of the user.
     */
    public void onStopUser(int userHandle) {}

    /**
     * Called when an existing user is stopping, for system services to finalize any per-user
     * state they maintain for running users.  This is called after all application process
     * teardown of the user is complete.
     * @param userHandle The identifier of the user.
     */
    public void onCleanupUser(int userHandle) {}

    /**
     * Publish the service so it is accessible to other services and apps.
     */
    protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }

    /**
     * Publish the service so it is accessible to other services and apps.
     */
    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        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(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);
    }
}

  其中比较感兴趣的是publishBinderService这个方法,在之前看到这个函数还不知道是做什么用的,现在看到这个方法的代码,瞬间清晰了,这个方法最终也还是会调用ServiceManager.addService方法,将service添加到ServiceManager中。

  另一个感兴趣的方法是publishLocalService,这个方法将一些要在system process中用到的service添加到LocalServices static类对象中,这个类内部通过ArrayMap将这些service记录起来,到后面需要使用就可以非常快速方便的取出来了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d 博主赞过: