美文网首页
Android Binder通信原理--04:Native-C\

Android Binder通信原理--04:Native-C\

作者: DarcyZhou | 来源:发表于2023-10-16 08:25 被阅读0次

本文转载自:Android10.0 Binder通信原理(四)-Native-C\C++实例分析

本文基于Android 10.0源码分析

1.摘要

  本节主要来讲解Android10.0 Binder的Native层实例流程。

2.概述

  在上一节中,我们知道了ServiceManager的启动过程,注册、获取服务的细节处理。服务的信息都存在于一个全局变量svclist的链表中。svclist对应的结构为svcinfo,其中有两个成员很重要:handle和name,handle代表了service的句柄,我们也可以理解为service的实体, name为service的名称。

  那么这个service的Binder句柄handle是怎么来的?在Native层,我们是如何进行注册、获取服务的,还不清楚。这一节,我们用一个Native层的实例来进行分析。遵循了不少网络大神的路线,也通过media的服务来进行分析。media的Binder服务注册,是一个很典型的Binder服务注册流程。

3.Native层的Binder架构

(1)服务端存在一个Binder实体--BBinder,以及对应的实体接口--BnInterface;
(2)客户端存在一个Binder代理--BpBinder,以及对应的代理接口--BpInterface;
(3)服务端通过Binder驱动向ServiceManager进行注册,把BBinder的实体对象存入ServiceManager,对应svcinfo的handle;
(4)客户端通过Binder驱动向ServiceManager发起查询请求,获取到service的Binder句柄--handle,进行一层转换变成BpBinder;
(5)客户端拿到了服务的代理后,就可以调用服务的代理接口来实现相应的功能。

Binder4-1.png

4.看源码前的思考

  假如是你,该如何来注册、获取一个服务?

按照我们正常的设计方法,服务注册该走下面几步:

(1)定义一个服务的名字;
(2)生成一个服务本身的实体BBinder;
(3)通过ServiceManager的代理接口,调用addService()这种接口实现服务注册,传入“服务名称”和“服务对象实体”,用来和ServiceManager的name-handle进行对应;
(4)开启一个线程池,把当前的线程加入线程池,方便管理,防止主线程的阻塞

服务获取该走下面几步:

(1)获取ServiceManager的代理对象,用于和ServiceManager进行通信;
(2)通过ServiceManager的代理接口,调用getService()这种接口来获取指向服务实体的代理接口;
(3)客户端通过调用已得到的service代理的成员函数,把自己的binder实体作为参数,传递到目标service进程;
(4)获得合法的服务代理对象。

5.概念理解

  在真正看代码前,需要先了解两个类:ProcessState和IPCThreadState这两个很重要类的概念。

5.1 ProcessState

  ProcessState从字面意思可以理解,表示是“进程状态”,代表了这个进程的行为,Android中,每个进程都是独立的,所以每个进程都要有一个“进程状态”--ProcessState。
  在Binder通信机制中,ProcessState使用了单例模式,即一个进程只有个ProcessState对象,一个进程中有很多个线程,不能每个线程都来new一个新的ProcessState(),采用单例模式后,每个线程都可以使用同一个ProcessState来和Binder驱动通信。
  ProcessState作为进程状态的记录器,主要用来打开Binder驱动获取句柄,mmap申请一块(1M-8K)的内存空间,设置Binder线程最大个数。

5.2 IPCThreadState

  IPCThreadState从字面意思可以理解,表示是“进程间通信的线程状态”,有了进程状态后,自然需要有线程状态。
  ProcessState代表了进程,IPCThreadState代表了线程。Android系统中有很多进程,进程间相互隔离,每个进程内部又有很多线程,线程之间也是相互独立的。所以说一个进程会存在很多个线程,每个线程都有自己的“线程状态”--IPCThreadState对象。这个对象存储在线程的本地存储区(TLS:Thread local storage)中,每个线程都拥有自己的TLS,并且是私有空间,线程之间不会共享。
  IPCThreadState对象根据key:gTLS去进行存储。通过pthread_getspecific/pthread_setspecific函数可以获取/设置这些空间中的内容。
  IPCThreadState负责与Binder驱动进行数据交互。

Binder4-2.png

5.3 BpBinder

  BpBinder展开后就是Binder Proxy,也就是Binder代理的含义。BpBinder是客户端用来与服务交互的代理类,负责实现跨进程传输的传输机制,不关心具体的传输内容。通信功能由其它类和函数实现,但由于这些类和函数被BpBinder代理,所以客户端需要通过BpBinder来发送Binder通信数据。

5.4 BBinder

  BBinder代表服务端,可以理解为服务的Binder实体,当服务端从Binder驱动中读取到数据后,由BBinder类进行处理。

6.Media的服务注册

Binder4-3.png

6.1 main()

// frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());     //获得ProcessState实例对象
    sp<IServiceManager> sm(defaultServiceManager()); //获取BpServiceManager对象
    ALOGI("ServiceManager: %p", sm.get());
    AIcu_initializeIcuOrDie();
    MediaPlayerService::instantiate();   //注册多媒体服务
    ResourceManagerService::instantiate();
    registerExtensions();
    ProcessState::self()->startThreadPool();    //启动Binder线程池
    IPCThreadState::self()->joinThreadPool();   //当前线程加入到线程池
}

media的服务注册流程分为以下几步:

(1)获得ProcessState实例对象;
(2)获取ServiceManager的代理对象--BpServiceManager;
(3)注册media服务;
(4)启动Binder线程池;
(5)把当前线程加入到线程池。

6.2 ProcessState::self()

  前面我们已经知道了ProcessState代表了进程状态,一个进程只有一个ProcessState对象。ProcessState采用了单例的模式保存了一个ProcessState全局对象--gProcess,供每个线程使用。
  从下面的文件可以猜到ProcessState.cpp 存在于一个so库中,即libbinder.so,service进程调用libbinder.so进行Binder通信。

 // frameworks/native/libs/binder/ProcessState.cpp
#ifdef __ANDROID_VNDK__
const char* kDefaultDriver = "/dev/vndbinder";
#else
const char* kDefaultDriver = "/dev/binder";
#endif
sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    //ProcessState的实例存在,直接返回该实例对象--单例模式
    if (gProcess != nullptr) {
        return gProcess;
    }
    //实例化ProcessState,kDefaultDriver 根据VNDK的宏定义来决定当前进程使用"/dev/binder" 还是"/dev/vndbinder"
    gProcess = new ProcessState(kDefaultDriver);
    return gProcess;
}
//--------------------------------------------
ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver)) //打开驱动,根据VNDK的宏定义来决定当前进程使用"/dev/binder" 还是"/dev/vndbinder",假设为"/dev/binder"
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) //Binder线程的最大个数16
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(nullptr)
    , mBinderContextUserData(nullptr)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
    if (mDriverFD >= 0) {
        // 向Binder驱动申请一块(1M-8K)的虚拟地址空间来接收事务。
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

ProcessState的对象创建也比较简单,根据VNDK的宏定义来决定当前进程使用"/dev/binder" 还是"/dev/vndbinder"来打开了binder驱动,这里假设为"/dev/binder"。向Binder驱动申请一块(1M-8K)的虚拟地址空间来接收事务。(1M-8K)在前面的入门篇已经讲解原因,这里不重复说明。变量说明:

  • mDriverFD:Binder驱动打开后,记录的句柄,用于访问Binder设备;
  • mMaxThreads:最大Binder线程个数;
  • BINDER_VM_SIZE:((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2),其中_SC_PAGE_SIZE为4K,即一个物理页的大小为4K,最终为(1M-8K)。

6.3 获取ServiceManager代理对象

defaultServiceManager()

当服务进程获取到了ProcessState对象后,接下来要拿到ServiceManager的代理对象--BpServiceManager。

// frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != nullptr) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        //当ServiceManager还未准备好,等待1秒后重新获取ServiceManager对象
        while (gDefaultServiceManager == nullptr) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(nullptr));
            if (gDefaultServiceManager == nullptr)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

ServiceManager的对象获取也采用了一个单例模式,一个进程中只要获取一次即可,对象存储在gDefaultServiceManager中。主要流程如下:

(1)获取ProcessState对象---ProcessState::self(),在上面的流程中可知ProcessState已获取,存入了全局变量中;
(2)获取BpBinder对象---ProcessState::getContextObject(nullptr);
(3)获取BpServiceManager对象---interface_cast<IServiceManager>。

6.3.1 ProcessState::getContextObject()

  getContextObject()调用getStrongProxyForHandle()进行处理,传入handle=0,在前面ServiceManager那一节我们知道,系统中约定了ServiceManager的handle=0。

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}
//---------------------------------------------------
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    //查找handle对应的资源项
    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                Parcel data;
                //通过ping操作测试binder是否准备就绪
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                if (status == DEAD_OBJECT)
                   return nullptr;
            }
            //当handle值所对应的IBinder不存在或弱引用无效时,创建一个BpBinder,handle=0
            //create的实现其实就是new BpBinder(0,trackedUid)
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
    return result;
}

getStrongProxyForHandle()的过程也很简单,当handle=0所对应的IBinder不存在或弱引用无效时,先看下Binder是否已经准备就绪,即ServiceManager是否已经就绪,准备好后,创建一个BpBinder(0,trackedUid),创建BpBinder对象中会将handle相对应Binder的弱引用增加1,最终返回一个BpBiner的对象。

  即当Service向ServiceManager进行注册时,Service变成了Client,ServiceManager变成了Server,需要先把Service 转换成一个BpBinder对象,作为Binder代理进行通信。所以 ProcessState::getContextObject() 就相当于 new BpBinder(0,trackedUid)

6.3.2 interface_cast<IServiceManager>

  真正获取ServiceManager的代理对象的是interface_cast<IServiceManager>方法。

// frameworks/native/libs/binder/include/binder/IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj); // 这里INTERFACE对应为IServiceManager
}

这里采用了C++的模板函数,interface_cast<IServiceManager>其实就是调用了IServiceManager::asInterface(obj); 这里的obj 就是new BpBinder(0)。但是IServiceManager中没有看到asInterface()的实现,我们就在IInterface.h进行查找,找到了asInterface()实现,分别在申明DECLARE_META_INTERFACE和实现IMPLEMENT_META_INTERFACE中。

// frameworks/native/libs/binder/include/binder/IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE)                               \
public:                                                                 \
    static const ::android::String16 descriptor;                        \
    static ::android::sp<I##INTERFACE> asInterface(                     \
            const ::android::sp<::android::IBinder>& obj);              \
    virtual const ::android::String16& getInterfaceDescriptor() const;  \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \
    static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl);     \
    static const std::unique_ptr<I##INTERFACE>& getDefaultImpl();       \
private:                                                                \
    static std::unique_ptr<I##INTERFACE> default_impl;                  \
public:                                                                 \

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const ::android::String16 I##INTERFACE::descriptor(NAME);           \
    const ::android::String16&                                          \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
            const ::android::sp<::android::IBinder>& obj)               \
    {                                                                   \
        ::android::sp<I##INTERFACE> intr;                               \
        if (obj != nullptr) {                                           \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == nullptr) {                                      \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl;           \
    bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\
    {                                                                   \
        if (!I##INTERFACE::default_impl && impl) {                      \
            I##INTERFACE::default_impl = std::move(impl);               \
            return true;                                                \
        }                                                               \
        return false;                                                   \
    }                                                                   \
    const std::unique_ptr<I##INTERFACE>& I##INTERFACE::getDefaultImpl() \
    {                                                                   \
        return I##INTERFACE::default_impl;                              \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

#define CHECK_INTERFACE(interface, data, reply)                         \
    do {                                                                \
      if (!(data).checkInterface(this)) { return PERMISSION_DENIED; }   \
    } while (false)

IServiceManager中的使用方法:

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

我这里就不进行展开了,有兴趣的可以尝试一下,最终IServiceManager::asInterface() 等价于new Bp##INTERFACE(obj),即 new BpServiceManager(obj)。所以:

gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(nullptr));

转换后变成:

gDefaultServiceManager = new BpServiceManager(new BpBinder(0,trackedUid));

BpServiceManager()的继承有必要展开下,方便后面的分析:

(1)class BpServiceManager : public BpInterface<IServiceManager>
(2)class BpInterface : public INTERFACE, public BpRefBase
(3)class BpRefBase : public virtual RefBase

下面的mRemote(o.get()) ,其实就是拿到传入的obj,即为new BpBinder(0,trackedUid)

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(nullptr), mState(0)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    if (mRemote) {
        mRemote->incStrong(this);           // Removed on first IncStrong().
        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    }
}

6.4 MediaPlayerService::instantiate()

//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

defaultServiceManager()->addService()等价调用BpServiceManager::addService(),其中service的name是“media.player”,service的对象是“new MediaPlayerService()”。
  MediaPlayerService继承自BnMediaPlayerService,BnMediaPlayerService继承自BnInterface,BnInterface继承自BBinder,最终转换为一个Binder实体--BBinder对象。

  类的继承关系如下:

Binder4-5.png

继续往下看BpServiceManager::addService()是如何工作的:

// frameworks/native/libs/binder/IServiceManager.cpp
virtual status_t addService(const String16& name, const sp<IBinder>& service,
                            bool allowIsolated, int dumpsysPriority) {
    Parcel data, reply;//定义data和reply的Parcel数据包
    //写入RPC头信息"android.os.IServiceManager"
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);//服务名为 "media.player"
    data.writeStrongBinder(service);//把一个binder实体“打扁”并写入parcel, 服务的实体对象:new MediaPlayerService()
    data.writeInt32(allowIsolated ? 1 : 0);//allowIsolated= false
    data.writeInt32(dumpsysPriority);//dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT
    //remote()函数返回的是mRemote,就是BpRefBase中的mRemote,即BpBinder对象。这里调用了BpBinder的transact()方法
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    return err == NO_ERROR ? reply.readExceptionCode() : err;
}

主要流程:

(1)准备两个Parcel结构:data,reply;
(2)组装Parcel数据;
(3)写入头信息:android.os.IServiceManager;
(4)写入服务名:media.player;
(5)写入服务的实体对象:new MediaPlayerService();
(6)调用remote的transact,发送ADD_SERVICE_TRANSACTION的命令进行服务的注册;
(7)得到返回的reply数据。

  最核心的就是 remote()->transact(ADD_SERVICE_TRANSACTION, XXX),这里的remote()函数返回的是mRemote,在上面我们理解到mRemote其实就是new BpBinder(0,trackedUid),最终转换为BpBinder->transact(ADD_SERVICE_TRANSACTION, XXX)。

  上面有一个要注意的地方data.writeStrongBinder(service); 最终调用的是flatten_binder(),目的是把一个Binder实体“压扁”并写入Parcel。这里"压扁"的含义,其实就是把Binder对象整理成flat_binder_object变量。如果压扁的是Binder实体,那么flat_binder_object用cookie域记录binder实体的指针,即BBinder指针,而如果打扁的是Binder代理,那么flat_binder_object用handle域记录的binder代理的句柄值。

// frameworks/native/libs/binder/Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;

    if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
        /* minimum priority for all nodes is nice 0 */
        obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
    } else {
        /* minimum priority for all nodes is MAX_NICE(19) */
        obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    }

    if (binder != nullptr) {
        BBinder *local = binder->localBinder(); //是否是Binder实体
        if (!local) {
            //是binder代理
            BpBinder *proxy = binder->remoteBinder();
            if (proxy == nullptr) {
                ALOGE("null proxy");
            }
            const int32_t handle = proxy ? proxy->handle() : 0;//记录Binder代理的句柄
            obj.hdr.type = BINDER_TYPE_HANDLE;
            obj.binder = 0; 
            obj.handle = handle; // handle域记录句柄
            obj.cookie = 0; 
        } else {
            //是binder实体
            if (local->isRequestingSid()) {
                obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
            }
            obj.hdr.type = BINDER_TYPE_BINDER;
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local); //cookie记录Binder实体的指针
        }
    } else {
        obj.hdr.type = BINDER_TYPE_BINDER;
        obj.binder = 0;
        obj.cookie = 0;
    }

    return finish_flatten_binder(binder, obj, out);
}

接着flatten_binder()调用了一个关键的finish_flatten_binder()函数。这个函数内部会记录下刚刚被扁平化的flat_binder_object在parcel中的位置。说得更详细点儿就是,parcel对象内部会有一个buffer,记录着parcel中所有扁平化的数据,有些扁平数据是普通数据,而另一些扁平数据则记录着binder对象。所以parcel中会构造另一个mObjects数组,专门记录那些binder扁平数据所在的位置,示意图如下:

Binder4-6.png

接下来看看传输过程BpBinder->transact(ADD_SERVICE_TRANSACTION,XXX)。

6.4.1 BpBinder::transact()

// 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::transact()就是调用IPCThreadState::self()->transact() 进行处理。

6.4.2 IPCThreadState::transact()

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

    flags |= TF_ACCEPT_FDS;
    ...
    // 传输数据
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);

    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }

    if ((flags & TF_ONE_WAY) == 0) {
        if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {
            if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {
                ALOGE("Process making non-oneway call but is restricted.");
                CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
                    ANDROID_LOG_ERROR);
            } else /* FATAL_IF_NOT_ONEWAY */ {
                LOG_ALWAYS_FATAL("Process may not make oneway calls.");
            }
        }
        //等待响应
        if (reply) {
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
        ...
    } else {
        //oneway,则不需要等待reply的场景
        err = waitForResponse(nullptr, nullptr);
    }

    return err;
}

writeTransactionData代码如下:

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    binder_transaction_data tr; //申请一个binder_transaction_data的结构

    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    tr.target.handle = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    const status_t err = data.errorCheck();  //错误检查
    if (err == NO_ERROR) {
        // 把Parcel的数据转换到binder_transaction_data中
        tr.data_size = data.ipcDataSize();
        // 这部分是待传递数据
        tr.data.ptr.buffer = data.ipcData(); 
        // 这部分是扁平化的binder对象在数据中的具体位置
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } else if (statusBuffer) {
        tr.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr.data_size = sizeof(status_t);
        tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0;
        tr.data.ptr.offsets = 0;
    } else {
        return (mLastError = err);
    }

    mOut.writeInt32(cmd);
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

writeTransactionData()主要就是把传入的Parcel数据,转换成binder_transaction_data,写入mOut,用来与Binder驱动交互。其中tr.data.ptr.buffer记录了Parcel传输的数据,tr.data.ptr.offsets记录下“待传数据”中所有binder对象的具体位置,如下图所示:

Binder4-7.png

当binder_transaction_data传递到binder驱动层后,驱动层可以准确地分析出数据中到底有多少binder对象,并分别进行处理,从而产生出合适的红黑树节点(Binder驱动层再分析,这里了解即可)。
  此时,如果产生的红黑树节点是binder_node的话,binder_node的cookie域会被赋值成flat_binder_object所携带的cookie值,也就是用户态的BBinder地址值。
  这个新生成的binder_node节点被插入红黑树后,会一直严阵以待,以后当它成为另外某次传输动作的目标节点时,它的cookie域就派上用场了,此时cookie值会被反映到用户态,于是用户态就拿到了BBinder对象。

  waitForResponse()先调用talkWithDriver()把mOut的数据发给Binder驱动,Binder驱动再和ServiceManager进行交互,进行服务注册,然后ServiceManager解析完成后,调用binder_send_reply()把返回的数据发送出来,其中的cmd为BR_XXX 响应码,请求的数据存入到IPCThreadState mIn的Parcel结构中.
  waitForResponse()根据 Binder驱动发来的BR_XXX请求码,进行相应的处理。mOut里面的BC_XXX请求码为BC_TRANSACTION, 根据Binder驱动中的交互流程,会先发一个 BR_TRANSACTION_COMPLETE响应码,目标进程收到事务后,处理BR_TRANSACTION事务,然后发送给当前进程,再执行BR_REPLY命令。
  waitForResponse()里面是一个while(1)循环,可以处理多个命令,只有进入goto finish后,循环才退出。协议码转换的流程,到下一节的Binder 驱动一节进行详细分析,这里只要了解一个大概即可,不要陷入死胡同。

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;

    while (1) {
        if ((err=talkWithDriver()) < NO_ERROR) break;
        ...

        cmd = (uint32_t)mIn.readInt32();

        switch (cmd) {
        case BR_TRANSACTION_COMPLETE: ...
            break;

        case BR_DEAD_REPLY: ...
            goto finish;

        case BR_FAILED_REPLY: ...
            goto finish;

        case BR_ACQUIRE_RESULT: ...
            goto finish;

        case BR_REPLY: ...
            goto finish;

        default:
            err = executeCommand(cmd);
            if (err != NO_ERROR) goto finish;
            break;
        }
    }
finish:
    if (err != NO_ERROR) {
        if (acquireResult) *acquireResult = err;
        if (reply) reply->setError(err);
        mLastError = err;
    }
    ...
    return err;
}

talkWithDriver()用来不停的和Binder驱动进行通信,ioctl()函数在传递BINDER_WRITE_READ语义时,既会使用“输入buffer”,也会使用“输出buffer”,所以IPCThreadState专门搞了两个Parcel类型的成员变量:mIn和mOut。mOut中的内容发出去,发送后的回复写进mIn。

  BINDER_WRITE_READ的命令发给Binder驱动后,ServiceManager有个循环不停的解析Binder驱动的BINDER_WRITE_READ信息,调用binder_parse()进行解析,我们前面addService()时,传入的code为ADD_SERVICE_TRANSACTION,在ServiceManager中解析后,对应的值为SVC_MGR_ADD_SERVICE,最终把服务的name和handle(对象) 存入到svclist中,ServiceManager再通过binder_send_reply()把返回的数据发送出来,在talkWithDriver()中填入mIn中,waitForResponse()进行最终的语义处理,发送出去。

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    if (mProcess->mDriverFD <= 0) {
        return -EBADF;
    }

    binder_write_read bwr;

    ...
    //如果仍在读取输入缓冲区中剩余的数据,并且调用方已请求读取下一个数据,则不希望写入任何内容。
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();  //把mOut的数据存入write_buffer中,

    // This is what we'll read.
    if (doReceive && needRead) {
        //接收数据缓冲区信息的填充。如果以后收到数据,就直接填在mIn中了
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();
    } else {
        //没有收到数据时,把read置空,binder只进行write处理
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }
    ...
    //当读缓冲和写缓冲都为空,则直接返回
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;

    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    status_t err;
    do {
    ...
#if defined(__ANDROID__)
        //通过ioctl不停的读写操作,跟Binder Driver进行通信
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif
        if (mProcess->mDriverFD <= 0) {
            err = -EBADF;
        }
        ...
    } while (err == -EINTR);//当被中断,则继续执行

    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else {
                mOut.setDataSize(0);
                processPostWriteDerefs();
            }
        }
        if (bwr.read_consumed > 0) {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        ...
        return NO_ERROR;
    }

    return err;
}

mIn和mOut的data会先整理进一个binder_write_read结构,然后再传给ioctl()函数。此时使用的文件描述符就是前文我们说的ProcessState中记录的mDriverFD,说明是向binder驱动传递语义。BINDER_WRITE_READ表示我们希望读写一些数据。这样就完成了BpBinder向远端--ServiceManager发起的传输流程。

  waitForResponse()收到BR_TRANSACTION响应码后,调用BBinder的transact()进行处理。

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::executeCommand(int32_t cmd)
{
...
 case BR_TRANSACTION:
    if (tr.target.ptr) {
        if (reinterpret_cast<RefBase::weakref_type*>(
                tr.target.ptr)->attemptIncStrong(this)) {
            //这里的cookie就是驱动层binder_node节点的cookie发挥作用,
            //拿到了一个合法的BBinder
            error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
                    &reply, tr.flags);
            reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
        } else {
            error = UNKNOWN_TRANSACTION;
        }

    } else {
        error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
    }
 ...
}

BBinder->transact() 中最重要的就是onTransact(),binder实体在本质上都是继承于BBinder的,而且我们一般都会重载onTransact()函数,所以上面这句onTransact()实际上调用的是具体binder实体的onTransact()成员函数。

// frameworks/native/libs/binder/Binder.cpp
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) {
        case PING_TRANSACTION:
            reply->writeInt32(pingBinder());
            break;
        default:
            err = onTransact(code, data, reply, flags);
            break;
    }

    if (reply != nullptr) {
        reply->setDataPosition(0);
    }

    return err;
}

MediaPlayerService继承自BnMediaPlayerService,最终继承自BBinder,上面执行onTransact时,其实对应的BBinder实体,也会执行该函数,就进入了BnMediaPlayerService::onTransact。

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
....
}

注册服务的流程简单的总结一下:

(1)服务进程先获得一个 ProcessState()的对象;
(2)获取ServiceManager的代理对象BpServiceManager,主要通过new BpBinder(0,xxx)得到;
(3)调用BpServiceManager的addService,组装一个Parce数据,传入服务名称、服务实体对象--BBinder、执行code-ADD_SERVICE_TRANSACTION;
(4)先通过IPCThreadThread的writeTransactionData()把上面的Parcel数据写入mOut,用来进行发送;
(5)通过IPCThreadThread的talkWithDriver()与Binder驱动通信,传递语义BINDER_WRITE_READ;
(6)ServiceManager有个循环不停的解析Binder驱动的BINDER_WRITE_READ信息,调用binder_parse()进行解;
(7)ServiceManager中解析后,ADD_SERVICE_TRANSACTION对应的值为SVC_MGR_ADD_SERVICE,最终把服务的name和handle存入到svclist中,ServiceManager再通过binder_send_reply()把返回的数据发送出来,在talkWithDriver()中填入mIn中,waitForResponse()进行最终的语义处理;
(8)waitForResponse()收到BR_TRANSACTION响应码后,最终后调用executeCommand()进行命令执行,根据逻辑处理,最终会调用到Binder实体的onTransact(),例如这里的BnMediaPlayerService::onTransact();
(9)最终完成服务的注册流程。

7.获取media的服务

  在第6节中,我们了解了media服务的注册流程,接下来我们一起看看,其他进程是如何获取media的服务来进行通信。
  在ServiceManager一节,我们知道了注册、获取服务我们都要通过ServiceManager进行处理,所以获取服务,大体还是分为下面几步:

(1)获取ServiceManager的代理对象BpServiceManager,用于和ServiceManager进行通信;
(2)通过ServiceManager的代理接口,调用getService()这种接口来获取指向服务实体的代理接口;
(3)客户端通过调用已得到的service代理的成员函数,把自己的binder实体作为参数,传递到目标service进程获得合法的服务代理对象。

  获取media服务序列图:

Binder4-8.png

7.1 IMediaDeathNotifier::getMediaPlayerService()

// frameworks/av/media/libmedia/IMediaDeathNotifier.cpp
IMediaDeathNotifier::getMediaPlayerService()
{
    ALOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService == 0) {
        //获取ServiceManager的代理对象BpServiceManager
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            //调用BpServiceManager的getService接口,来获取服务名称为“media.player”的Binder服务对象
            binder = sm->getService(String16("media.player"));
            if (binder != 0) {
                break;
            }
            ALOGW("Media player service not published, waiting...");
            usleep(500000); // 如果media的服务还没有准备好,休眠0.5秒进行等待
        } while (true);

        if (sDeathNotifier == NULL) {
            sDeathNotifier = new DeathNotifier();        //创建死亡通知对象
        }
        binder->linkToDeath(sDeathNotifier);//将死亡通知连接到binder
        // 转换得到服务对象
        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;
}

流程如下:

(1)获取ServiceManager的代理对象BpServiceManager;
(2)调用BpServiceManager的getService接口,来获取服务名称为“media.player”的Binder 服务对象;
(3)创建死亡通知对象;
(4)将死亡通知连接到binder;
(5)得到服务对象。

  通过defaultServiceManager()来获取ServiceManager的对象,我们接下来主要来看getService的流程。

7.2 BpServiceManager::getService()

// frameworks/native/libs/binder/IServiceManager.cpp
// defaultServiceManager->getService()其实就是BpServiceManager->getService。
virtual sp<IBinder> getService(const String16& name) const
{
    //检索指定服务是否存在
    sp<IBinder> svc = checkService(name);
    if (svc != nullptr) return svc;

    //如果ProcessState和Binder驱动交互的是"/dev/vndbinder",那么isVendorService为True,表明Vendor进程之间可以进行Binder通信
    const bool isVendorService =
        strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
    const long timeout = uptimeMillis() + 5000;

    if (!gSystemBootCompleted && !isVendorService) {
        //vendor分区的代码不能访问system的属性
        char bootCompleted[PROPERTY_VALUE_MAX];
        property_get("sys.boot_completed", bootCompleted, "0");
        gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false;
    }

    //vendor分区的服务sleepTime 为100ms, system为1000ms
    const long sleepTime = gSystemBootCompleted ? 1000 : 100;

    int n = 0;
    while (uptimeMillis() < timeout) {
        n++;
        ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(),
            ProcessState::self()->getDriverName().c_str());
        usleep(1000*sleepTime);

        sp<IBinder> svc = checkService(name);
        if (svc != nullptr) return svc;
    }
    ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
    return nullptr;
}

getService()的核心就是调用checkService()来检查服务是否存在,如果不存在,继续等待查找。注意:vendor分区的服务等待时间为100ms,system分区的为1000ms.

7.3 BpServiceManager::checkService()

  checkService()和前面的addService类似,都是组织一个Parcel结构,然后调用BpBinder的transact()方法,把服务信息和传输code--CHECK_SERVICE_TRANSACTION发给Binder驱动。

// frameworks/native/libs/binder/IServiceManager.cpp#checkService
virtual sp<IBinder> checkService( const String16& name) const
{
    Parcel data, reply;
    //写入RPC头信息"android.os.IServiceManager"
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name); //写入服务的名称
    //remote()函数返回的是mRemote,就是BpRefBase中的mRemote,即BpBinder对象。这里调用了BpBinder的transact()方法
    remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    return reply.readStrongBinder();
}

BpBinder的transact()的流程这里就不展开,上面addService()已经有了详细的说明。CHECK_SERVICE_TRANSACTION在ServiceManager中对应的是SVC_MGR_CHECK_SERVICE(),从svclist中,根据服务的name查到对应的handle,最终得到服务的对象。

  和addService类似,ServiceManager查到对应的handle后,把handle存入reply,addService的reply没有数据getService的reply有数据,返回BR_REPLY相应码。

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    ...
    case BR_REPLY:
        {
            binder_transaction_data tr;
            err = mIn.read(&tr, sizeof(tr));
            ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
            if (err != NO_ERROR) goto finish;

            if (reply) {
                if ((tr.flags & TF_STATUS_CODE) == 0) {
                    reply->ipcSetDataReference(
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(binder_size_t),
                        freeBuffer, this);
                } else {
                    err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
                    freeBuffer(nullptr,
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(binder_size_t), this);
                }
            } else {
                freeBuffer(nullptr,
                    reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                    tr.data_size,
                    reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                    tr.offsets_size/sizeof(binder_size_t), this);
                continue;
            }
        }
        goto finish;
    ...
}

7.4 Parcel::readStrongBinder()

  checkservice()收到ServiceManager发来的reply后,调用readStrongBinder()来获取服务的对象。主要在unflatten_binder中,根据flat的type是handle还是实体,从而返回BpBinder对象或者BBinder实体。

// frameworks/native/libs/binder/Parcel.cpp
sp<IBinder> Parcel::readStrongBinder() const
{
    sp<IBinder> val;
    readNullableStrongBinder(&val);
    return val;
}
//----------------------------
status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
{
    return unflatten_binder(ProcessState::self(), *this, val);
}
//----------------------------
status_t unflatten_binder(const sp<ProcessState>& proc,
    const Parcel& in, sp<IBinder>* out)
{
    const flat_binder_object* flat = in.readObject(false);

    if (flat) {
        switch (flat->hdr.type) {
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast<IBinder*>(flat->cookie);
                return finish_unflatten_binder(nullptr, *flat, in); //返回BBinder实体
            case BINDER_TYPE_HANDLE:
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast<BpBinder*>(out->get()), *flat, in); //返回BpBinder代理对象
        }
    }
    return BAD_TYPE;
}

获取服务的流程简单的总结一下:

(1)客户端进程获取ServiceManager的代理对象BpServiceManager,主要通过new BpBinder(0,xxx)得到;
(2)调用BpServiceManager的getService,再到checkService(),然后组装一个Parce数据,传入服务名称、传输code-CHECK_SERVICE_TRANSACTION;
(3)先通过IPCThreadThread的writeTransactionData()把上面的Parcel数据写入mOut,用来进行发送;
(4)通过IPCThreadThread的talkWithDriver()与Binder驱动通信,传递语义BINDER_WRITE_READ;
(5)ServiceManager有个循环不停的解析Binder驱动的BINDER_WRITE_READ信息,调用binder_parse()进行解析;
(6)ServiceManager中解析后,CHECK_SERVICE_TRANSACTION对应的值为SVC_MGR_CHECK_SERVICE,从svclist中,根据服务的name查到对应的handle,ServiceManager再通过binder_send_reply()把返回的数据发送出来,在talkWithDriver()中填入mIn中,waitForResponse()进行最终的语义处理,发送出去。

注意:

  • 当请求服务的进程与服务属于不同进程,则为请求服务所在进程创建binder_ref对象,指向服务进程中的binder_node,最终readStrongBinder()时,返回的是BpBinder对象;

  • 当请求服务的进程与服务属于同一进程,则不再创建新对象,只是引用计数加1,并且修改type为BINDER_TYPE_BINDER或BINDER_TYPE_WEAK_BINDER。最终readStrongBinder()时,返回的是BBinder对象的真实子类。

8.协议码的转换流程及不同Android版本的变化

  Binder通信协议是基于Command-Reply的方式的。

  Android9.0之前的协议码流程:

Binder4-9.png

  Android9.0及之后的协议码流程:

  上面第5步的BR_TRANSACTION_COMPLETE被延迟到第10步 ,Android做deferred_thread_work,延迟 TRANSACTION_COMPLETE,因此不会立即返回到用户空间;这允许目标进程立即开始处理此事务,从而减少延迟。然后,当目标回复(或出现错误)时,我们将返回TRANSACTION_COMPLETE。

Binder4-10.png

注册服务的详细代码流程,kernel细节的代码这里就不贴了,后面在内核章节进行详细解析:

  1. BpServiceManager::addService()时,调用writeStrongBinder(service),把服务对象写入BBinder,作为Binder实体,调用remote()->transact()处理,code:ADD_SERVICE_TRANSACTION,最终到IPCThreadState::transact();

  2. IPCThreadState::transact()调用writeTransactionData(),组装CMD:BC_TRANSACTION进入 binder_transaction_data tr,tr写入mOut;

  3. IPCThreadState::transact()再调用waitForRespose和Binder驱动进行交互,第一次mOut里面存的是BC_TRANSACTION及binder_transaction_data的值,mIn没有值;

  4. talkWithDriver()中,此时,bwr.write_size >0 ; bwr.read_size = 0,调用ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)和binder驱动进行交互;

  5. binder_ioctl()->binder_ioctl_write_read()先从用户空间读到上面的bwr的内容,根据此时的bwr.write_size >0 ; bwr.read_size = 0, 只进入binder_thread_write();

  6. binder_thread_write()根据前面的CMD:BC_TRANSACTION从而进入binder_transaction();

  7. binder_transaction()是个重要的流程,主要用来进行事务处理;首先创建一个binder_transaction结构的对象t,并插入到自己的binder_transaction堆栈中;

  8. 分配一块buffer:t->buffer,用于保存上面mOut中的data和mObjects 中的offset数据;

  9. 从data中解析出所有的binder实体并为其创建binder_node和binder_ref ,data解析的数据存在结构 flat_binder_object中;

  10. transaction事务处理完成后,tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE, t->work.type = BINDER_WORK_TRANSACTION;

  11. 接下来,延迟TRANSACTION_COMPLETE,因此我们不会立即返回到用户空间,这允许目标进程立即开始处理此事务,从而减少延迟。然后,当目标(ServiceManager)回复reply(或出现错误)时,我们将返回TRANSACTION_COMPLETE。主要通过thread->process_todo = false;来促成;

  12. binder_transaction()调用binder_proc_transaction() 将transaction发送到进程(ServiceManager)并将其唤醒,调用wake_up_interruptible()进行唤醒;

  13. 唤醒ServiceManager后,回到binder_ioctl_write_read(),调用copy_to_user(),把binder_write_read的数据传到用户空间;

  14. ServiceManager的binder_loop()中,不同循环通过 ioctl(,BINDER_WRITE_READ,XXX)从用户空间获取数据, 此时bwr.write_size = 0,bwr.read_size> 0;

  15. 又进入进入到了Binder驱动,binder_ioctl()->binder_ioctl_write_read() ->binder_thread_read()

  16. binder_thread_read()中,前面的 type=BINDER_WORK_TRANSACTION,且tr有数据,将会发送cmd:BR_TRANSACTION到ServiceManager, 调用copy_to_user()把数据发给用户空间ServiceManager;

  17. ServiceManager的binder_parse()解析内核传来的binder_write_read数据,根据cmd:BR_TRANSACTION, 调用svcmgr_handler处理,code=SVC_MGR_ADD_SERVICE, 然后调用binder_send_reply() cmd_reply=BC_REPLY,cmd_free=BC_FREE_BUFFER, 发给Binder驱动,其中write_size > 0;

  18. Binder驱动,binder_ioctl()->binder_ioctl_write_read()->binder_thread_write(),读取ServiceManager传来的数据,进入binder_transaction(),cmd=BC_REPLY,唤醒Client进程,把BR_TRANSACTION_COMPLETE分别发给ServiceManager 和Client进程;

  19. IPCThreadState收到BR_TRANSACTION_COMPLETE后,把数据写入mIn,mOut移除内容,继续调用talkWithDriver(),向Binder驱动发起BINDER_WRITE_READ请求,此时mOut无值,mIn有内容;

  20. Binder驱动进入binder_thread_read(),根据ServiceManager发来的reply数据,发送BR_REPLY给client;

  21. IPCThreadState waitForResponse()收到BR_REPLY后,释放内存空间。

9.Media Client\Server交互流程

Binder4-11.png

10.代码路径

/frameworks/av/media/mediaserver/main_mediaserver.cpp

/frameworks/native/libs/binder/IServiceManager.cpp

/frameworks/native/libs/binder/ProcessState.cpp

/frameworks/native/libs/binder/IPCThreadState.cpp

/frameworks/native/libs/binder/BpBinder.cpp

/frameworks/native/libs/binder/Parcel.cpp

/frameworks/native/libs/binder/include/binder/IInterface.h

/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

相关文章

网友评论

      本文标题:Android Binder通信原理--04:Native-C\

      本文链接:https://www.haomeiwen.com/subject/foambdtx.html