Android系统服务分析之服务注册过程

来源:互联网 发布:ubuntu查看64位 32位 编辑:程序博客网 时间:2024/06/13 00:50

下面主要是围绕frameworks中service是如何通过binderIPC来起作用的。以WindowManagerService为例:

首先在frameworks/base/services/java/com/android/server/SystemServer.java中注册WindowManagerService服务

private void startOtherServices() {    ......    WindowManagerService wm = null;       ......    traceBeginAndSlog("StartWindowManagerService");    wm = WindowManagerService.main(context, inputManager,           mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,           !mFirstBoot, mOnlyCore);    ServiceManager.addService(Context.WINDOW_SERVICE, wm);    ......}
调用ServiceManager的addService()函数注册服务,传入参数服务名称和服务的实例。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);        }    }

可以看到实际上是调用ServiceManagerNative的asInterface()方法.

private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // Find the service manager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;    }

通过getIServiceManager()方法得到IServiceManager类型的对象sServiceManager,主要经过两个步骤:通过Native层的调用得到ServiceManager的远程对象BpBinder,然后将BpBinder封装成ServiceManagerProxy对象,如下:

frameworks/base/core/java/android/os/ServiceManagerNative.java

public abstract class ServiceManagerNative extends Binder implements IServiceManager{    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);    }    ......}

此段代码主要是得到ServiceManager的代理对象ServiceManagerProxy,ServiceManagerProxy会与Binder驱动通信。即上文SystemServer.java文件中调用的addService()方法实际上调用的是ServiceManagerProxy的addService()方法。

public void addService(String name, IBinder service, boolean allowIsolated)            throws RemoteException {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();                            // 声明两个Parcel类型的对象data,reply用于存放数据        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();    }

传给addService()的参数是服务的名称和服务的实例,这两个参数会写入到Parcel类型的data中(三个参数是要发送出去的RPC数据)。mRemote是持有Context Manager的BpBinder对象,mRemote调用transact()方法传送RPC数据和RPC代码(ADD_SERVICE_TRANSACTION),执行Binder IPC处理。下面我们来看看BpBinder中transact()是如何来处理RPC数据和代码的。

frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::transact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    // Once a binder has died, it will never come back to life.    if (mAlive) {        status_t status = IPCThreadState::self()->transact(            mHandle, code, data, reply, flags);        if (status == DEAD_OBJECT) mAlive = 0;        return status;    }    return DEAD_OBJECT;}

可以发现BpBinder的trasact()方法中增加了第一个参数,它是自身所持有的服务Handle,在本例子中是使用持有ContextManager服务Handle值得BpBinder,所以mHandle的值为0。在这个方法中实际调用的是IPCThreadState的transct()方法。

frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,                                  uint32_t code, const Parcel& data,                                  Parcel* reply, uint32_t flags){    status_t err = data.errorCheck();    if (err == NO_ERROR) {        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);                   //调用writeTransactData()函数创建binder_transaction_data数据结构,该结构与Binder西医一起构成BinderIPC数据   }    ......    if (reply) {            err = waitForResponse(reply);                          //调用waitForResponse()函数,将Binder IPC数据传递给Binder Driver        } else {            Parcel fakeReply;            err = waitForResponse(&fakeReply);        }    }    ......}


接下来是Binder Driver中的处理过程,这里就不继续分析了。

native层的服务注册过程与此类似,下面以native层的服务添加过程做总结:

首先添加服务文件NewService.cpp文件,在main()函数中添加如下代码:

int main(){     ......     sp<ProcessState> proc(ProcessState::self());     sp<IServiceManager> sm = defaultServiceManager();     sm->addService(“service.name”,new NewService());     ProcessState::self()->startThreadPool();     IPCThreadState::self()->joinThreadPool();     ......}

然后定义INewService接口,INewService接口是和NewService相关的,提供getService(),addService()等方法

class INewService: public IInterface{     public:     DECLARE_META_INTERFACE(NewService);     virtual getService() = 0;     virtual addService() = 0;}

定义BnNewService和BpNewService:BnNewService是需要有头文件的,只是将INewService接口加入到Binder架构中,不参与实际的getService和addService应用逻辑

class BnNewService: public BnInterface<INewService>{     public:         virtual status_t    onTransact( uint32_t code,                                     const Parcel& data,                                     Parcel* reply,                                     uint32_t flags = 0);};

DECLARE_META_INTERFACE方法申明宏之后,就饿可以在INewService.cpp文件中实现了。

IMPLEMENT_META_INTERFACE(NewService, "android.xxx.INewService");

接下来就是BpNewService了:

class BpNewService : public BpInterface<INewService> {    BpNewService(const sp<IBinder>& impl): BpInterface<IServiceManager>(impl)    {    }    virtual sp<IBinder> getService(const String16& name) const    {        .......    }    virtual sp<IBinder> addService(const String16& name) const    {        .......    }    ......}

大体就是这样了,如果有写的不太好的或者理解不对的地方欢迎指出,谢谢。


原创粉丝点击