您的位置:首页 > 移动开发 > Android开发

android2.3 --- Service Manager分析

2016-04-09 15:34 316 查看
http://blog.csdn.net/andyhuabing/article/details/7459073

android2.3 ---  Service Manager分析

Android系统Binder机制的总管是Service Manager,所有的Server(System Server)都需要向他注册,应用程序需要向其查询相应的服务。可见其作用是多么的重要,那么我们这里就要重点介绍一下这个。

这里以java层加入ServiceManager及getService为数据流分析一下。

复习一下典型的Binder模式,有利于后面的理解:

1、客户端通过某种方式得到服务器端的代理对象。从客户端角度看来代理对象和他的本地对象没有什么差别。它可以像其他本地对象一样调用其方法,访问其变量。

2、客户端通过调用服务器代理对象的方法向服务器端发送请求。

3、代理对象把用户请求通过Android内核(Linux内核)的Binder驱动发送到服务器进程。 

4、服务器进程处理用户请求,并通过Android内核(Linux内核)的Binder驱动返回处理结果给客户端的服务器代理对象。 

5、客户端收到服务器端的返回结果。

JAVA层代码分析:

ServiceManager.java (frameworks\base\core\java\android\os)

对于xxxManager获取服务端service基本如此用法:

利用ContextImpl.java中的 

public Object getSystemService(String name) 

然后再调用:

ServiceManager.getService(ServiceName);

获取相应的服务端

ex:

@Override

public Object getSystemService(String name) {
if (WIFI_SERVICE.equals(name)) {

  return getWifiManager();

}

-->

private WifiManager getWifiManager()

{

    synchronized (sSync) {

        if (sWifiManager == null) {

            IBinder b = ServiceManager.getService(WIFI_SERVICE);

            IWifiManager service = IWifiManager.Stub.asInterface(b);

            sWifiManager = new WifiManager(service, mMainThread.getHandler());

        }

    }

    return sWifiManager;

}

ok,知道了客户端获取一个Service的方法之后,我们回到ServiceManager的服务端:

private static IServiceManager getIServiceManager() {

    if (sServiceManager != null) {

        return sServiceManager;

    }

    // Find the service manager

    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

    return sServiceManager;

}

BinderInternal.getContextObject() @ BinderInternal.java  是一个native 函数:

android_os_BinderInternal_getContextObject @ android_util_Binder.cpp

返回一个 BinderProxy对象保存到类成员mRemote(ServiceManagerProxy类成员)

public abstract class ServiceManagerNative extends Binder implements IServiceManager

ServiceManagerNative 继承自 Binder 并实现了 IServiceManager 接口,利用 asInterface()则提供一个 ServiceManagerProxy 代理对象使用

class ServiceManagerProxy implements IServiceManager

定义了类ServiceManagerProxy(代理),ServiceManagerProxy继承自IServiceManager,并实现了其声明的操作函数,只会被ServiceManagerNative创建,它实现了IServiceManager的接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。

ok,我们沿着代码继续往前走:

class ServiceManagerProxy implements IServiceManager {

    public ServiceManagerProxy(IBinder remote) {

        mRemote = remote;

    }

    

    public IBinder asBinder() {

        return mRemote;  // 这是一个BinderProxy对象

    }

    public IBinder getService(String name) throws RemoteException {

        Parcel data = Parcel.obtain();

        Parcel reply = Parcel.obtain();

        data.writeInterfaceToken(IServiceManager.descriptor);

        data.writeString(name);

        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

        IBinder binder = reply.readStrongBinder();

        reply.recycle();

        data.recycle();

        return binder;

    }

}

上层先利用Parcel对象将数据进行序列化,然后利用transact将数据传给binder驱动,根据 mRemote 是一个 BpBinder 对象继续追踪:

JNI层代码分析:android_util_Binder.cpp 

java 层通过 Binder 对象调用jni函数:

Binder.java: Binder实现的IBinder的接口,他的大部分函数都是通过JNI调用底层实现的BinderProxy是JAVA层的关键类,在JNI通过 gBinderProxyOffsets 来使用

这里只关心它的 onTransact 函数即可

BpBinder 在 BpBinder.h 实现:

class BpBinder : public IBinder

{

    virtual status_t    transact(   uint32_t code,

                                    const Parcel& data,

                                    Parcel* reply,

                                    uint32_t flags = 0);

}

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;

}

3、C++ native层实现 service操作实现,其实java层的直接利用jni写入到binder驱动层了:

IServiceManager.cpp (frameworks\base\libs\binder)

class BpServiceManager : public BpInterface<IServiceManager>

{

public:

    // 获取Service服务端

    virtual sp<IBinder> getService(const String16& name) const

    {

        unsigned n;

        for (n = 0; n < 5; n++){

            sp<IBinder> svc = checkService(name);

            if (svc != NULL) return svc;

            LOGI("Waiting for service %s...\n", String8(name).string());

            sleep(1);

        }

        return NULL;

    }

    // 添加Service到ServiceManager管理器

    virtual status_t addService(const String16& name, const sp<IBinder>& service)

    {

        Parcel data, reply;

        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

        data.writeString16(name);

        data.writeStrongBinder(service);

        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

        return err == NO_ERROR ? reply.readExceptionCode() : err;

    }

}

到了这里:

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

// ----------------------------------------------------------------------

status_t BnServiceManager::onTransact(

    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

一般都以为服务端继承BnServiceManager类实现即可:

ServiceManager.h (frameworks\base\cmds\runtime)

class BServiceManager : public BnServiceManager

其实这里不是的,这是在模拟器上的实现方法,请看其下面的Android.mk文件:

ifeq ($(TARGET_SIMULATOR),true)

... 

include $(BUILD_EXECUTABLE)

endif

那么这里到底是怎么回事呢?JAVA层利用jni也是如此操作的。

这里是通过 IPCThreadState 类直接将binder请求写入到binder驱动(/dev/binder),这里简要说一下简单的流程,后续还会继续深入这个问题:

addService @ IServiceManager.cpp

status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

-->

transact @ IPCThreadState

transact() --> writeTransactionData() 写入到binder驱动,这就是核心所在。。。

现在就进入到最重要的 servicemanager 大总管角色中了

源码路径:frameworks\base\cmds\servicemanager\service_manager.c

servicemanager 是一个进程,在init.rc脚本中开机就启动:

service servicemanager /system/bin/servicemanager

    user system

    critical

    onrestart restart zygote

    onrestart restart media

    
从其main中开始分析:

main @ service_manager.c

int main(int argc, char **argv)

{

    struct binder_state *bs;

    void *svcmgr = BINDER_SERVICE_MANAGER;

    bs = binder_open(128*1024);

    if (binder_become_context_manager(bs)) {

        LOGE("cannot become context manager (%s)\n", strerror(errno));

        return -1;

    }

    svcmgr_handle = svcmgr;

    binder_loop(bs, svcmgr_handler);

    return 0;

}

调用binder_open打开binder设备(/dev/binder),其次它调用了binder_become_context_manager函数,这个函数使他自己变为了"Server大总管"
int binder_become_context_manager(struct binder_state *bs)

{

    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);

}
即成为一个0号句柄,所有的进程都可以通过id=0来访问它。

Service Manager作为一个Server大总管,本身也是一个server。既然是一个server就要时刻准备为客户端提供服务。最好Service Manager调用binder_loop进入到循环状态,并提供了一个回调函数,等待用户的请求。注意他的Service Manager的客户端既包括应用程序(查询和获取服务),也包括Server(注册服务)。

只要server向binder设备写入请求注册Service时,Service Manager的服务处理回调函数将会被调用

这里的回调函数就是 svcmgr_handler:

int svcmgr_handler(struct binder_state *bs,

                   struct binder_txn *txn,

                   struct binder_io *msg,

                   struct binder_io *reply)

{

    // 获取请求数据

    strict_policy = bio_get_uint32(msg);

    s = bio_get_string16(msg, &len);

    switch(txn->code) {

    case SVC_MGR_GET_SERVICE:  // 获取service服务

    case SVC_MGR_CHECK_SERVICE:

        s = bio_get_string16(msg, &len);

        ptr = do_find_service(bs, s, len);

        if (!ptr)

            break;

        bio_put_ref(reply, ptr);

        return 0;

    case SVC_MGR_ADD_SERVICE: // 注册service服务

        s = bio_get_string16(msg, &len);

        ptr = bio_get_ref(msg);

        if (do_add_service(bs, s, len, ptr, txn->sender_euid))

            return -1;

        break;

    case SVC_MGR_LIST_SERVICES: { // 列举service服务

        unsigned n = bio_get_uint32(msg);

        si = svclist;

        while ((n-- > 0) && si)

            si = si->next;

        if (si) {

            bio_put_string16(reply, si->name);

            return 0;

        }

        return -1;

    }

}

这里也是对请求的服务回写到binder驱动,别忘记了客户端同步处理:

transact @ IPCThreadState.cpp

    if ((flags & TF_ONE_WAY) == 0) {

        if (reply) {

            err = waitForResponse(reply);

        } else {

            Parcel fakeReply;

            err = waitForResponse(&fakeReply);

        }

    } else {

        err = waitForResponse(NULL, NULL);

    }
--> 这里利用talkWithDriver()利用:

ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) 请求与回应数据。

IPCThreadState 是一个非常关键的类,由其直接于binder驱动打交道,后文将会重点分析。

模块层次基本如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: