android binder解析

android binder解析  

2013-04-20 09:27:48|  分类: android |  标签:binder  ipc  surfaceflinger  anr  |举报|字号 订阅

一直对android的binder机制比较困惑,出了问题时也手足无措。看了一些资料,感觉似懂非懂,于是萌生了一个想法,一定要自己跟一根binder流程,这样有个亲身经历后,能够加深对binder的了解。

这里以surfaceflinger的远程调用为例,分析一下binder流程。碰巧手头上有一个anr trace文件,里面有surfaceflinger native端的stack trace。从trace更能印证自己总结的东西。

1. binder概述

binder涉及到proxy端和native端。proxy为client侧,native为server侧。

拿SurfaceFlinger类来讲,要实现binder远程调用,需要继承自BnXXX类:
frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BinderService,                                                                     
                       public BnSurfaceComposer,

这里的关键就是BnSurfaceComposer。继承了BinderService后,程序可以通过一种简单方式来publish服务:
frameworks/native/cmds/surfaceflinger/main_surfaceflinger.cpp
main()
  SurfaceFlinger::publishAndJoinThreadPool(true);

这个函数会创建一个SurfaceFlinger对象,并通过远程调用将它注册到service manager中:
    static void publishAndJoinThreadPool(bool allowIsolated = false) {
        sp sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }

好了,回过头来看看BnSurfaceComposer。

frameworks/native/include/gui/ISurfaceComposer.h
class ISurfaceComposer: public IInterface
class BnSurfaceComposer: public BnInterface

在frameworks/native/include/binder/IInterface.h中, BnInterface为声明为:
template
class BnInterface : public INTERFACE, public BBinder

继续看各类的父类,可以看到BnSurfaceComposer的继承关系为:
BnSurfaceComposer -> BnInterface ->  ISurfaceComposer & BBinder
ISurfaceComposer -> IInterface -> RefBase
BBinder -> IBinder -> RefBase
在以上这些类中,我们需要实现BnSurfaceComposer和ISurfaceComposer,其它的都是android库提供实现。BnSurfaceComposer实现了onTransact(),会调用子类的override函数来处理。这里子类就是SurfaceFlinger。

 

对于Proxy端,我们需要实现BpXXX类:
class BpSurfaceComposer : public BpInterface

BpSurfaceComposer的继承关系为:
BpSurfaceComposer -> BpInterface -> ISurfaceComposer & BpRefBase
BpRefBase -> RefBase
这里我们需要实现BpSurfaceComposer。在BpSurfaceComposer的函数中,一般都是通过remote()->transact()将命令发送到服务端:
    virtual sp createConnection()
    {
        uint32_t n;
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
        return interface_cast(reply.readStrongBinder());
    }

总结一下,要实现native端,需要以下几步:
(1) 实现ISurfaceComposer
(2) 实现BpSurfaceComposer,里面各调用通过remote()->transact()发送到服务端
(3) 实现BnSurfaceComposer,里面实现onTransact()来处理命令
(4) SurfaceFlinger继承BnSurfaceComposer,然后实例化SurfaceFlinger并注册到service manager

2. 注册和获取服务
注册服务的代码如下:
        sp sm(defaultServiceManager());
        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
这里其实也用到了binder机制,因为服务端和service manager是不同的进程。
defaultServiceManager(),BinderService.h
  gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL));
    getStrongProxyForHandle(0),ProcessState.cpp
  return gDefaultServiceManager;

sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  See comment
        // in getWeakProxyForHandle() for more info about this.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

看到了吗,这里根据handle创建了一个BpBinder对象并返回。返回的对象被interface_cast转换,之后就可以通过IServiceManager进行远程调用了。注册服务和获取服务的服务端都在service manager中,代码位于:
frameworks/base/cmds/servicemanager/service_manager.c

注册服务时,需要传入服务名和对象,服务名由SERVICE::getServiceName()获得。

获取服务时,需要指定服务名:
frameworks/native/libs/gui/SurfaceComposerClient.cpp
void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {                                                                    
        usleep(250000);
    }

frameworks/native/include/binder/IServiceManager.h
template
status_t getService(const String16& name, sp* outService)                                                             
{
    const sp sm = defaultServiceManager();
    if (sm != NULL) {
        *outService = interface_cast(sm->getService(name));
        if ((*outService) != NULL) return NO_ERROR;
    }
    return NAME_NOT_FOUND;
}

调用到IServiceManager类:
frameworks/native/libs/binder/IServiceManager.cpp
    virtual sp getService(const String16& name) const                                                                   
    {
        unsigned n;
        for (n = 0; n < 5; n++){
            sp svc = checkService(name);
            if (svc != NULL) return svc;
            ALOGI("Waiting for service %s...\n", String8(name).string());
            sleep(1);
        }
        return NULL;
    }

checkService()的实现:
    virtual sp checkService( const String16& name) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
        return reply.readStrongBinder();
    }
在结尾,根据service manager的返回调用readStrongBinder:
sp Parcel::readStrongBinder()
  status_t unflatten_binder(const sp& proc, const Parcel& in, wp* out)
    sp ProcessState::getStrongProxyForHandle(int32_t handle) // 或者为getWeakProxyForHandle
这里,getStrongProxyForHandle会根据handle来创建一个BpBinder,该binder就表示客户端需要的服务,与提供的名称对应。binder随后被interface_cast转换为INTERFACE类型,这里就是ISurfaceComposer。转换时调用到了以下函数:
template
inline sp interface_cast(const sp& obj)
{
    return INTERFACE::asInterface(obj);
}

进而调用到ISurfaceComposer::asInterface。在frameworks/native/libs/gui/ISurfaceComposer.cpp中,使用到了IMPLEMENT_META_INTERFACE:
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");

该宏在IInterface.h中被扩展,其中包含asInterface函数:
    android::sp I##INTERFACE::asInterface(                \
            const android::sp& obj)                   \
    {                                                                   \
        android::sp intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }  
在这里,创建了BpSurfaceComposer并返回,参数为getService返回的IBinder对象。

3. 客户端远程调用
远程调用是BpSurfaceComposer中通过remote()->transact()
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
这里有命令,传给服务端的数据data,以及返回的结果reply。这里的remote()返回什么对象呢?


BpSurfaceComposer的继承关系为:
BpSurfaceComposer -> BpInterface
BpInterface -> ISurfaceComposer & BpRefBase
BpRefBase -> RefBase

remote()为BpRefBase的成员函数,返回mRemote:
inline  IBinder* remote() { return mRemote; }

BpRefbase的构造函数中,mRemote被赋值为sp&的参数:
BpRefBase::BpRefBase(const sp& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)

从前一节的分析得知,获取远程对象时,返回的IBinder对象作为参数传到BpSurfaceComposer构造函数,从而导致基类BpRefBase的构造函数被调用。因此,此处的mRemote极为service manager返回的IBinder对象,其实就是new的BpBinder(handle)。

所以,remote()->transact()调用到了BpBinder::transact():
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;
}

继续往下跟会发现,transact调用会将command/data/reply等参数写入到/dev/binder节点,将这些参数传入内核。

下面是一个anr traces文件中截取的system_server中WindowManager线程的stack trace:
 
    

"WindowManager" prio=5 tid=14 NATIVE | group="main" sCount=1 dsCount=0 obj=0x41306db8 self=0x40e41b30 | sysTid=413 nice=-4 sched=0/0 cgrp=apps handle=1754226200 | state=S schedstat=( 4332243000 4585147000 20578 ) utm=321 stm=112 core=1 #00 pc 00016fe4 /system/lib/libc.so (__ioctl+8) #01 pc 0002a97d /system/lib/libc.so (ioctl+16) #02 pc 00016ba1 /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+132) #03 pc 0001709d /system/lib/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+44) #04 pc 000172b7 /system/lib/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+114) #05 pc 00014a3b /system/lib/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+34) #06 pc 000265d7 /system/lib/libgui.so #07 pc 00028073 /system/lib/libgui.so (android::SurfaceComposerClient::destroySurface(int)+14) #08 pc 0002749f /system/lib/libgui.so (android::SurfaceControl::destroy()+14) #09 pc 00058139 /system/lib/libandroid_runtime.so #10 pc 0001e290 /system/lib/libdvm.so (dvmPlatformInvoke+112) #11 pc 0004d411 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+396) #12 pc 00038c05 /system/lib/libdvm.so (dvmCheckCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+8) #13 pc 000276a0 /system/lib/libdvm.so #14 pc 0002b57c /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184) #15 pc 0005fc31 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+272) #16 pc 0005fc5b /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20) #17 pc 000547d7 /system/lib/libdvm.so #18 pc 0000e3d8 /system/lib/libc.so (__thread_entry+72) #19 pc 0000dac4 /system/lib/libc.so (pthread_create+160) at android.view.Surface.nativeDestroy(Native Method) at android.view.Surface.destroy(Surface.java:395) at com.android.server.wm.WindowStateAnimator.destroySurfaceLocked(WindowStateAnimator.java:795) at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedInner(WindowManagerService.java:9451) at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLockedLoop(WindowManagerService.java:8286) at com.android.server.wm.WindowManagerService.performLayoutAndPlaceSurfacesLocked(WindowManagerService.java:8229) at com.android.server.wm.WindowManagerService.access$300(WindowManagerService.java:172) at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:7715) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.os.HandlerThread.run(HandlerThread.java:60)



4. 服务端处理命令
对于SurfaceComposer来讲,服务端为运行在进程/system/bin/surfaceflinger中的SurfaceFlinger对象。/system/bin/surfaceflinger的main函数如下:
frameworks/native/cmds/surfaceflinger/main_surfaceflinger.cpp
int main(int argc, char** argv) {
    SurfaceFlinger::publishAndJoinThreadPool(true);
    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    ProcessState::self()->setThreadPoolMaxThreadCount(4);
    return 0;
}

publishAndJoinThreadPool会启动一个线程池:
ProcessState::self()->startThreadPool();

该调用会创建一个名为Binder_1的线程,该线程的作用就是不停读写binder,并处理命令:
void IPCThreadState::joinThreadPool(bool isMain)
{
        result = talkWithDriver();
        if (result >= NO_ERROR) {
            //...

            result = executeCommand(cmd);
        }
}

由于此时参数为true,这是主线程,它还负责创建新的线程来处理客户端的命令。如果由新的客户端连入,executeCommand收到内核发出的BR_SPAWN_LOOPER命令时,会创建一个新线程,线程名依次为Binder_2, Binder_3, ...

status_t IPCThreadState::executeCommand(int32_t cmd)
{
    case BR_SPAWN_LOOPER:
        mProcess->spawnPooledThread(false);
        break;
}

对于普通的命令,executeCommand会从binder_transaction_data中获取BBinder对象,调用其transact函数:
    sp b((BBinder*)tr.cookie);
    const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
    if (error < NO_ERROR) reply.setError(error);

在Binder.cpp中,transact调用到onTransact():
status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);

    status_t err = NO_ERROR;
    switch (code) {

        default:
            err = onTransact(code, data, reply, flags);
            break;
    }
}

该远程对象实际为一个BnSurfaceComposer对象,因此,onTransact()调用的是子类的函数。在BnSurfaceComposer::onTransact中,各命令被处理,对应到了SurfaceFinger类的各函数。

下面是一个anr traces文件中截取的surfaceflinger中Binder_1线程的stack trace:
 
    

"Binder_1" sysTid=283 #00 pc 0000dc70 /system/lib/libc.so (__futex_syscall3+8) #01 pc 00012e14 /system/lib/libc.so (__pthread_cond_timedwait_relative+48) #02 pc 00012e70 /system/lib/libc.so (__pthread_cond_timedwait+60) #03 pc 0001c713 /system/lib/libgui.so (android::BufferQueue::dequeueBuffer(int*, unsigned int, unsigned int, unsigned int, unsigned int)+554) #04 pc 0001e0e9 /system/lib/libgui.so (android::BnSurfaceTexture::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+236) #05 pc 000143c9 /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+60) #06 pc 00016fad /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+520) #07 pc 000173d5 /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+184) #08 pc 0001b179 /system/lib/libbinder.so #09 pc 00010f57 /system/lib/libutils.so (android::Thread::_threadLoop(void*)+114) #10 pc 00010abd /system/lib/libutils.so #11 pc 00012dd0 /system/lib/libc.so (__thread_entry+48) #12 pc 00012528 /system/lib/libc.so (pthread_create+172)

你可能感兴趣的:(android binder解析)