Android Service Manager

1.介绍
Service Manager是Binder进程间通信的核心服务,它是Binder进程间通信的上下文管理者(Context Manager),向Client提供获取Service代理对象的服务.Service Manager运行在独立的进程中,所以Client和service都需要通过进程间通信机制来与他交互.从这个角度看Service Manager自身也是一个特殊的Service.注意Service Manager管理的是AMS,PMS,WMS等系统服务,而不是应用组件service.
Service Manager是init进程在系统启动的时候启动的,其启动脚本为;
system/core/roogir/init.rc
service servicemanager /system/bin/servicemanager            ----以service的形式启动
    class core                                                                           ----这是个核心类服务                                   
    user system                                                                        ----以系统身份运行
    group system                                                                      ----属于系统组
    critical                                                                                 ----这是个关键服务,不能退出,一旦退出就会被系统重启,如果4分钟内重启次数超过4次系统就重启.
    onrestart restart healthd                                                     ----servicemanager重启,这些service也会跟着重启
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm


2.启动过程
ServiceManager在native层运行,代码为:
frameworks/native/cmds/servicemanager/service_manager.c

其main函数为:

int main(int argc, char **argv)
{
    struct binder_state *bs;

    bs = binder_open(128*1024);                             ----打开设备文件dev/binder
    if (!bs) {
        ALOGE("failed to open binder driver\n");
        return -1;
    }

    if (binder_become_context_manager(bs)) {                ----将自己注册为binder进程间通信机制的上下文管理者
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    selinux_enabled = is_selinux_enabled();
    sehandle = selinux_android_service_context_handle();

    if (selinux_enabled > 0) {
        if (sehandle == NULL) {
            ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
            abort();
        }

        if (getcon(&service_manager_context) != 0) {
            ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
            abort();
        }
    }

    union selinux_callback cb;
    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);
    cb.func_log = selinux_log_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);

    svcmgr_handle = BINDER_SERVICE_MANAGER;
    binder_loop(bs, svcmgr_handler);                        ----循环等和处理client进程的通信请求

    return 0;
}
从main函数可以看出ServiceManager的启动过程一共只有三步:

1) 打开设备文件dev/binder

2) 将自己注册为binder进程间通信机制的上下文管理者

3) 循环等和处理client进程的通信请求


3.在JAVA层调用ServiceManager
相关类:
./frameworks/base/core/java/android/os/IServiceManager.java
./frameworks/base/core/java/android/os/ServiceManager.java
./frameworks/base/core/java/android/os/ServiceManagerNative.java
./frameworks/base/core/java/android/os/ServiceManagerNative.java@ServiceManagerProxy
其中IServiceManager.java是接口文件,定义了
    获取service,如果service没有准备好,该方法会block当前线程几秒钟
    public IBinder getService(String name) throws RemoteException;
    获取service并立即返回
    public IBinder checkService(String name) throws RemoteException;
    注册service
    public void addService(String name, IBinder service, boolean allowIsolated)throws RemoteException;
    列出所有Running service
    public String[] listServices() throws RemoteException;
四个方法.
ServiceManager.java文件实现了这四个方法

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;
    }

    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;
    }

    public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

    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);
        }
    }
    
    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;
        }
    }

    public static String[] listServices() throws RemoteException {
        try {
            return getIServiceManager().listServices();
        } catch (RemoteException e) {
            Log.e(TAG, "error in listServices", e);
            return null;
        }
    }

    public static void initServiceCache(Map cache) {
        if (sCache.size() != 0) {
            throw new IllegalStateException("setServiceCache may only be called once");
        }
        sCache.putAll(cache);
    }
}

从该类文件可以看出四个方法都是以public static的形式实现,及只需要直接使用ServiceManager的类名调用即可.
这里选择public static void addService(String name, IBinder service, boolean allowIsolated)进行分析,该方法用于在servivemanager里面注册service.需要注意的是真正注册的并不是service本身,而是其对应类型为JavaBBinder的binder本地对象,这样在client请求service的时候,Binder本地对象就将请求数据发给对应的service.
该方法只执行了一句代码:
getIServiceManager().addService(name, service, allowIsolated);三个参数分别为service名称;service相对应的IBinder对象;是否允许远程调用.
getIServiceManager()的关键执行语句为:sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
BinderInternal.getContextObject()返回的是一个BinderProxy对象,他是C++层Binder在java层的Binder代理,实现了IBinder接口.BinderProxy内部有一个类型为int的成员变量mObject,他指向C++层的Binder代理对象.这样就可以把Java层和C++层的Binder代理对象关联起来,可以通过C++层的Binder代理对象实现Java层的功能.
然后看ServiceManagerNative的asInterface方法:

    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ServiceManagerProxy(obj);
    }

关键语句就是return new ServiceManagerProxy(obj);
new了一个servicemanager的代理并将BinderProxy对象传了进去,及mRemote.
ServiceManagerProxy的构造函数:

ServiceManagerProxy的构造函数:
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }

及getIServiceManager()方法返回的是servicemanager的远程代理对象ServiceManagerProxy,addService(String name, IBinder service, boolean allowIsolated)方法最终进入ServiceManagerProxy执行

    public void addService(String name, IBinder service, boolean allowIsolated)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        data.writeInt(allowIsolated ? 1 : 0);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

在这里进行IPC通信,而Binder机制都是通过Parcel传数据.其中data是用于传出数据,reply用于接受传回的数据.将相关数据都写到data后调用mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);将命令发送出去.

该命令最终在frameworks/native/libs/binder/IServiceManager.cpp的

    virtual status_t addService(const String16& name, const sp& service,
            bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

方法里面进行处理.

到此,就完成了从Java到native层的service注册过程.



你可能感兴趣的:(android,技术)