Binder 學(xué)習(xí)筆記

這不是一篇詳細(xì)介紹 Binder 實(shí)現(xiàn)原理的文章,因?yàn)榻榻B Binder 的相關(guān)文章已經(jīng)非常多了,比如 :
Android深入淺出之Binder機(jī)制
Android Bander設(shè)計(jì)與實(shí)現(xiàn) - 設(shè)計(jì)篇
Android Binder機(jī)制系列文章
但是作為一個(gè)普通的 Android 程序員,尤其是不熟悉 C語(yǔ)言,Linux內(nèi)核及驅(qū)動(dòng),JNI 的程序員,面對(duì)大量的底層源碼分析,還是多次中途放棄。

這次終于一鼓作氣看完了 Android Binder機(jī)制系列文章,總算搞清了 Binder 的來(lái)龍去脈,所以這里整理記錄下來(lái)。如果你也想徹底搞清 Binder 的設(shè)計(jì)與實(shí)現(xiàn),那么可以Android Binder機(jī)制系列文章為主進(jìn)行學(xué)習(xí),遇到困惑的地方可以參考本文,說(shuō)不定會(huì)有幫助。

2 源碼及工具準(zhǔn)備

2.1 源碼下載

我們的目的只是為了查看 Binder 源碼,所以不需要安裝 repo,也不用下載整個(gè)的 AOSP 項(xiàng)目,只要下載一些我們會(huì)用到的源碼就好了。
所有的Android的源碼都可以在這里下載 https://android.googlesource.com/
下面列出 Binder學(xué)習(xí)中需要用到的幾個(gè)包:

下載方法:點(diǎn)擊上面鏈接,打開(kāi)后選擇任意一個(gè)分支,點(diǎn)擊tgz鏈接,就可以下載源碼壓縮包了。有些源碼已經(jīng)跟很多博客中分析的不一樣了,不過(guò)改動(dòng)都不大。一般下載master分支就可以了,不過(guò) kernel/common 的master分支是空的,可選擇 android-4.4 分支下載。

下載源碼壓縮包

2.2 源碼閱讀工具

在閱讀 Binder 源碼時(shí),經(jīng)常需要查看各種方法的調(diào)用,類的定義等等,需要頻繁的查找和跳轉(zhuǎn),所以一個(gè)順手的工具可以大大提高閱讀效率。
推薦使用 Sublime Text 3,mac/windows通吃。裝好之后還需要安裝 Ctags 插件,用于建立其代碼索引,可以方便的跳轉(zhuǎn)查看方法的實(shí)現(xiàn)。

常用操作:

  • Ctrl + P,輸入文件名稱,回車打開(kāi)文件
  • Ctrl + P,輸入 @+函數(shù)名,查找某個(gè)函數(shù)

3 Binder 概述

3.1 什么是 Binder

在不同的上下文環(huán)境中提到 binder,代表的意思也不同:

  • 從 Android 系統(tǒng)層面來(lái)說(shuō),binder 指的一種實(shí)現(xiàn)進(jìn)程間通訊的機(jī)制
  • 在 Linux 內(nèi)核中, binder 指的是一個(gè)虛擬設(shè)備的驅(qū)動(dòng),可以想象成兩個(gè)進(jìn)程間通訊的管道,用戶態(tài)的進(jìn)程 A 只需要通過(guò)系統(tǒng)調(diào)用向 binder 驅(qū)動(dòng)發(fā)送命令,binder 驅(qū)動(dòng)就會(huì)搞定一切,把命令傳送給指定的進(jìn)程 B,并把處理結(jié)果返回給 A。 binder 封裝了底層對(duì)線程、內(nèi)存復(fù)雜的管理操作,暴露給用戶進(jìn)程的只是幾個(gè)命令,極大的簡(jiǎn)化了進(jìn)程間的通訊。

3.2 Binder 整體架構(gòu)

Binder 的設(shè)計(jì)整體上是典型的 C/S 架構(gòu),Binder 架構(gòu)中的4個(gè)角色完全可以拿典型的 TCP/IP 網(wǎng)絡(luò)結(jié)構(gòu)來(lái)類比:

  • Binder Client:發(fā)起服務(wù)請(qǐng)求的客戶端
  • Binder Server:響應(yīng)服務(wù)請(qǐng)求的服務(wù)端
  • ServiceManager:提供查找服務(wù),添加服務(wù)的DNS
  • Binder 驅(qū)動(dòng):定義通訊協(xié)議,完成數(shù)據(jù)的封裝和傳輸?shù)腡CP/IP通訊協(xié)議

3.3 Binder 典型交互

  1. Server 將自己注冊(cè)到 ServiceManager 中
  2. Client 通過(guò)服務(wù)名稱向 ServiceManager 查找對(duì)應(yīng)服務(wù)
  3. ServiceManager 根據(jù)服務(wù)名稱查找到 Server ,在內(nèi)核中建立對(duì)應(yīng)的 Binder 實(shí)體,并將該實(shí)體對(duì)應(yīng)的 Binder 引用返回給Client
  4. Client 通過(guò) Binder 引用向 Server 發(fā)起請(qǐng)求
  5. Binder 驅(qū)動(dòng)根據(jù) Binder 引用找到對(duì)應(yīng)的 Binder 實(shí)體,將客戶端的請(qǐng)求發(fā)送給 Binder 實(shí)體處理
  6. Binder 驅(qū)動(dòng)將處理后的結(jié)果返回給 Client

接下來(lái)將對(duì) Binder 架構(gòu)中的關(guān)鍵環(huán)節(jié)的流程進(jìn)行一一個(gè)梳理

4 ServiceManager

ServiceManager 作為注冊(cè)和查找服務(wù)的中心,其實(shí)本質(zhì)上也是一個(gè)特殊的 server,只是它必須要先于其他的 server 啟動(dòng),這樣其他的 server 在初始化的時(shí)候就可以把自己注冊(cè)到 ServiceManager 中。

通過(guò)在 init.rc 添加啟動(dòng)腳本,系統(tǒng)在啟動(dòng)初始化時(shí)就會(huì)調(diào)用 service_manager 的 main 入口函數(shù)完成 ServiceManager 的啟動(dòng)和初始化:

platform/native/cmds/servicemanager/service_manager.c

int main()
{
    struct binder_state *bs;

    bs = binder_open(128*1024); //1.打開(kāi) binder 驅(qū)動(dòng),獲取文件描述符
    // 略
    if (binder_become_context_manager(bs)) { // 2.將 ServiceManager 注冊(cè)成為“DNS”
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    // 略
    binder_loop(bs, svcmgr_handler); // 3.進(jìn)入循環(huán)等待接收客戶端發(fā)來(lái)的請(qǐng)求

    return 0;
}

略去無(wú)用代碼,關(guān)鍵的部分只有三步,注釋已經(jīng)寫(xiě)明,下面看看每一步具體做了什么

4.1 binder_open()

platform/native/cmds/servicemanager/binder.c

struct binder_state *binder_open(size_t mapsize)
{
    struct binder_state *bs;
    struct binder_version vers;

    bs = malloc(sizeof(*bs));
    ... 
    bs->fd = open("/dev/binder", O_RDWR | O_CLOEXEC); 1. 打開(kāi) binder 設(shè)備驅(qū)動(dòng)
    ...
    }
    ...
    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); // 2.建立內(nèi)存映射
 
    }

    return bs;
}

open 函數(shù)是一個(gè)系統(tǒng)函數(shù),用于打開(kāi)第一個(gè)參數(shù)指明的設(shè)備,對(duì)應(yīng)的函數(shù)在 binder 驅(qū)動(dòng)* /kernel/common/drivers/android/binder.c*(注意跟 servicemanager 目錄下的binder.c區(qū)分,后者只是封裝了一些 servicemanager 跟 binder 驅(qū)動(dòng)交互的操作)的源碼中定義

kernel/common/drivers/android/binder.c

static const struct file_operations binder_fops = {
    .owner = THIS_MODULE,
    .poll = binder_poll,
    .unlocked_ioctl = binder_ioctl,
    .compat_ioctl = binder_ioctl,
    .mmap = binder_mmap,
    .open = binder_open,
    .flush = binder_flush,
    .release = binder_release,
};

這個(gè)結(jié)構(gòu)體定義了open 函數(shù)對(duì)應(yīng)的函數(shù)指針,所以實(shí)際的函數(shù)是 binder_open,這里不展開(kāi)了主要是理清流程。
接下來(lái) mmap 操作完成用戶內(nèi)存到內(nèi)核內(nèi)存的映射。

4.2 binder_become_context_manager()

該函數(shù)內(nèi)部通過(guò) ioctl 函數(shù)向 binder 驅(qū)動(dòng)發(fā)送一個(gè) BINDER_SET_CONTEXT_MGR 的命令,使當(dāng)前進(jìn)程成為系統(tǒng)的 ServiceManager。該命令的處理在 * /kernel/common/drivers/android/binder.c* 的 binder_ioctl 函數(shù)中,binder 驅(qū)動(dòng)會(huì)為建立 ServiceManager 對(duì)應(yīng)的 binder 實(shí)體。(注意:這里的實(shí)現(xiàn)已經(jīng)跟多數(shù)文章中講的不同,不再是用一個(gè)全局變量保存該 binder 實(shí)體,而是保存在 binder_proc->binder_context->binder_context_mgr_node這個(gè)變量中)

4.3 binder_loop()

platform/native/cmds/servicemanager/binder.c

void binder_loop(struct binder_state *bs, binder_handler func)
{
    readbuf[0] = BC_ENTER_LOOPER;
    binder_write(bs, readbuf, sizeof(uint32_t));

    for (;;) {
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);   
    }
}

主要的操作就只有上面幾行代碼,其余的都已省略。
binder_write函數(shù)會(huì)調(diào)用 ioctl 發(fā)送 BC_ENTER_LOOPER 命令告訴 binder 驅(qū)動(dòng)當(dāng)前線程已進(jìn)入消息循環(huán)狀態(tài)。接下來(lái)的死循環(huán),從 binder 驅(qū)動(dòng)讀取消息到 &bwr,如果沒(méi)有消息就會(huì)阻塞直到被喚醒,讀取到消息后再調(diào)用binder_parse解析 &bwr 中的消息內(nèi)容。
binder_parse會(huì)調(diào)用 func 函數(shù)處理請(qǐng)求。func 參數(shù)傳入的值是一個(gè)指向svcmgr_handler函數(shù)的函數(shù)指針,所以具體的如添加查找函數(shù)的請(qǐng)求處理主要都在 svcmgr_handler函數(shù)中了。
處理完請(qǐng)求回到binder_parse 后調(diào)用binder_send_reply向驅(qū)動(dòng)返回處理的結(jié)果(根據(jù)請(qǐng)求類型如果不需要回復(fù)就沒(méi)有這一步)

5 獲取 ServiceManager

客戶端想要獲取系統(tǒng)服務(wù),首先就要向 ServiceManager 請(qǐng)求服務(wù)端的代理對(duì)象,而各類系統(tǒng)服務(wù) 也要在系統(tǒng)啟動(dòng)時(shí)先注冊(cè)到 ServiceManager。所以如何獲取 ServiceManager 就成為了第一個(gè)要解決的問(wèn)題。
IServiceManager::defaultServiceManager() 就是用來(lái)獲得一個(gè) ServiceManager 服務(wù)代理的函數(shù)。

platform/native/libs/binder/IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

一個(gè)典型的單例模式,關(guān)鍵就是下面這一句了,信息量很大,一點(diǎn)一點(diǎn)拆開(kāi)來(lái)看

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

###5.1 ProcessState::self()
這里又是一個(gè)單例模式獲取一個(gè) `ProcessState` 對(duì)象,在構(gòu)造函數(shù)中,打開(kāi)了 `/dev/binder` 設(shè)備,保存了文件句柄。然后調(diào)用mmap()映射內(nèi)存到當(dāng)前進(jìn)程的虛擬地址空間。

###5.2 getContextObject()
實(shí)際上調(diào)用了 `getStrongProxyForHandle(handle)`,這個(gè)函數(shù)返回一個(gè) BpBinder(handle),這里 handle 為0,也即 ServiceManager 的句柄值。

###5.3 interface_cast<IServiceManager>
這部分是最暗藏玄機(jī)也比較不好理解的部分,前面我們已經(jīng)獲得了一個(gè) BpBinder 對(duì)象,而這里最終要返回一個(gè) IServiceManager 對(duì)象,然而這兩者并沒(méi)有任何的繼承關(guān)系,所以肯定不是簡(jiǎn)單的強(qiáng)轉(zhuǎn)。看這個(gè)模板函數(shù)的定義。

frameworks/native/include/binder/IInterface.h

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}

把 `INTERFACE` 替換成 `IServiceManager`,然而 `IServiceManager` 中并沒(méi)有 `asInterface` 這個(gè)方法。注意到 *IServiceManager.h* 中有一句宏調(diào)用: 

DECLARE_META_INTERFACE(ServiceManager)

而 *IServiceManager.cpp* 中也有一句宏調(diào)用:

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

這里的聲明和實(shí)現(xiàn)里有包括了 asInterface 方法,這兩個(gè)宏定義在 IInterface.h 中:

frameworks/native/include/binder/IInterface.h

define DECLARE_META_INTERFACE(INTERFACE) \

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();                                            \

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 != NULL) {                                              \
        intr = static_cast<I##INTERFACE*>(                          \
            obj->queryLocalInterface(                               \
                    I##INTERFACE::descriptor).get());               \
        if (intr == NULL) {                                         \
            intr = new Bp##INTERFACE(obj);                          \
        }                                                           \
    }                                                               \
    return intr;                                                    \
}                                                                   \
I##INTERFACE::I##INTERFACE() { }                                    \
I##INTERFACE::~I##INTERFACE() { }    
把兩個(gè)宏展開(kāi)之后就變成了:

define DECLARE_META_INTERFACE(IServiceManager) \

static const android::String16 descriptor;                          \
static android::sp<IServiceManager> asInterface(                    \
        const android::sp<android::IBinder>& obj);                  \
virtual const android::String16& getInterfaceDescriptor() const;    \
IServiceManager();                                                  \
virtual ~IServiceManager();                                         \

define IMPLEMENT_META_INTERFACE(IServiceManager, "android.os.IServiceManager") \

const android::String16 IServiceManager::descriptor("android.os.IServiceManager"); \
const android::String16&                                                           \
        IServiceManager::getInterfaceDescriptor() const {                          \
    return IServiceManager::descriptor;                                            \
}                                                                                  \
android::sp<IServiceManager> IServiceManager::asInterface(                         \
        const android::sp<android::IBinder>& obj)                                  \
{                                                                                  \
    android::sp<IServiceManager> intr;                                             \
    if (obj != NULL) {                                                             \
        intr = static_cast<IServiceManager*>(                                      \
            obj->queryLocalInterface(                                              \
                    IServiceManager::descriptor).get());                           \
        if (intr == NULL) {                                                        \
            intr = new BpServiceManager(obj);                                      \
        }                                                                          \
    }                                                                              \
    return intr;                                                                   \
}                                                                                  \
IServiceManager::IServiceManager() { }                                             \
IServiceManager::~IServiceManager() { }
我們重點(diǎn)關(guān)注 `asInterface` 方法,這里傳入的 `obj` 參數(shù)就是前面得到的 `BpBinder(0)` 對(duì)象,`queryLocalInterface` 的默認(rèn)實(shí)現(xiàn)在 *IBinder.cpp* 中,它返回 null,所以這里 `intr == null`,最終就構(gòu)造了 `BpServiceManager(obj)` 返回,而`BpServiceManager` 正是 `IServiceManager` 的一個(gè)實(shí)現(xiàn)類,它也是 ServiceManager 在客戶端的代理對(duì)象。

###5.4 總結(jié)
借用 [這篇文章](http://wangkuiwu.github.io/2014/09/01/Binder-Introduce/#anchor2_1_2) 的一張圖來(lái)梳理一下 Binder 架構(gòu)中各個(gè)類的關(guān)系:
![](http://upload-images.jianshu.io/upload_images/1423045-c8c99b7f51653151.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
1. 服務(wù)接口定義服務(wù)提供的業(yè)務(wù)邏輯,比如 IServiceManager,定義了 getService,addService 等。
2. 本地服務(wù),也即服務(wù)端,是真正實(shí)現(xiàn)業(yè)務(wù)邏輯的對(duì)象。
3. 遠(yuǎn)程服務(wù),也即客戶端,或者代理端,比如 BpServiceManager,里面保存了一個(gè) BpBinder(實(shí)際在構(gòu)造函數(shù)時(shí)保存在父類 `BpRefBase.mRemote`  中,`通過(guò) remote()`  方法獲得),作為服務(wù)端的代理,主要職責(zé)是封裝請(qǐng)求,并向 Binder 驅(qū)動(dòng)發(fā)起請(qǐng)求,Binder 驅(qū)動(dòng)會(huì)負(fù)責(zé)把請(qǐng)求發(fā)送到對(duì)應(yīng)的服務(wù)端。這部分后面還會(huì)再做講解
4. Binder 驅(qū)動(dòng)收到代理發(fā)起的請(qǐng)求,最終會(huì)調(diào)用到 BBinder.onTransact 方法,所以本地服務(wù)只要實(shí)現(xiàn) onTransact 方法就能處理客戶端發(fā)來(lái)的請(qǐng)求了,這部分后面還會(huì)再做講解。
5. BpInterface<INTERFACE> 和 BnInterface<INTERFACE> 都定義在 Interface.h 中,這里的  INTERFACE 即是服務(wù)接口。

# 6 注冊(cè)服務(wù)到ServiceManager
獲取到 IServiceManager,就可以調(diào)用其 addService 方法,將服務(wù)添加到 ServiceManager 了,注意這時(shí)候服務(wù)扮演的是客戶端的角色,ServiceManager 扮演的是服務(wù)端的角色。
### 6.1 addService 

platform/native/libs/binder/IServiceManager.BpServiceManager

virtual status_t addService(const String16& name, const sp<IBinder>& 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;
}

可以看到這里把請(qǐng)求的參數(shù)打包到 Parcel 中(關(guān)于 Parcel 打包數(shù)據(jù)的原理這里就不具體講了,可以參考[這里](http://wangkuiwu.github.io/2014/09/05/BinderCommunication-AddService01)),注意 `data.writeStrongBinder(service);` 這句,這里的 service 是一個(gè) BnXXX,也即一個(gè)本地服務(wù)對(duì)象,在寫(xiě)入的時(shí)候會(huì)被轉(zhuǎn)換為一個(gè) flat_binder_object 結(jié)構(gòu)體寫(xiě)入,關(guān)于這個(gè)結(jié)構(gòu)體的說(shuō)明,參見(jiàn) [這里](http://wangkuiwu.github.io/2014/09/02/Binder-Datastruct/#anchor1_7)。
接下來(lái)`remote()->transact()`,這里的 remote() 前面已經(jīng)說(shuō)了,返回之前保存進(jìn)去的 BpBinder,BpBinder 的 transact 方法最終調(diào)用到 `IPCThreadState::self()->transact()`,到這里,實(shí)際跟 binder 驅(qū)動(dòng)打交道的類   `IPCThreadState 終于出現(xiàn)了。

### 6.2 IPCThreadState.transact()
`IPCThreadState::self()` 獲取調(diào)用進(jìn)程的 IPCThreadState 的單例,如果首次調(diào)用,會(huì)進(jìn)行打開(kāi)binder驅(qū)動(dòng),內(nèi)存映射等操作,和前面ServiceManager的啟動(dòng)類似。
精簡(jiǎn)后保留主要邏輯的 transact() 代碼:

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) {
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}

if ((flags & TF_ONE_WAY) == 0) {
    if (reply) {
        err = waitForResponse(reply);
    } 
}
return err;

}

可以看到主要涉及兩個(gè)函數(shù) `writeTransactionData`,`waitForResponse`

### 6.3 writeTransactionData()
這里必須先介紹 IPCThreadState 兩個(gè) Parcel 類型的成員變量,mIn 和 mOut,分別用來(lái)保存從 binder 驅(qū)動(dòng)讀取的數(shù)據(jù)和即將向 binder 驅(qū)動(dòng)寫(xiě)入的數(shù)據(jù)。而 `writeTransactionData()` 這個(gè)函數(shù)的作用就是把數(shù)據(jù)二次封裝到 mOut 中,這里又必須借一張圖來(lái)說(shuō)明了:
![](http://upload-images.jianshu.io/upload_images/1423045-c388a9297203228d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
有效數(shù)據(jù)對(duì)應(yīng)傳入的 data 參數(shù),也就是在6.1節(jié)封裝的那個(gè) Parcel,而經(jīng)過(guò)`writeTransactionData()` 的再次封裝之后, mOut = binder_transaction_data 結(jié)構(gòu) + BC_TRANSACTION(一個(gè)整數(shù)值)。后面會(huì)看到在發(fā)給 binder 驅(qū)動(dòng)之前數(shù)據(jù)還會(huì)經(jīng)過(guò)一層封裝到 `binder_write_read` 結(jié)構(gòu)中。

###6.4 waitForResponse()
精簡(jiǎn)后保留主要邏輯的代碼:

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_t cmd;
int32_t err;

while (1) {
    if ((err=talkWithDriver()) < NO_ERROR) break;   
    if (mIn.dataAvail() == 0) continue;     
    cmd = (uint32_t)mIn.readInt32();
    
    switch (cmd) {
    case BR_TRANSACTION_COMPLETE:
        if (!reply && !acquireResult) goto finish;
        break;
    
    case BR_REPLY:
        {
            binder_transaction_data tr;
            err = mIn.read(&tr, sizeof(tr));
            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(NULL,
                        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(NULL,
                    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;

    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;

}

這里的邏輯相對(duì)復(fù)雜,不過(guò)整體上看,主要是一個(gè)死循環(huán),當(dāng)滿足某些特定條件時(shí)才會(huì)跳出,下面具體分析死循環(huán)里的幾個(gè)關(guān)鍵步驟。

####6.4.1 第一次調(diào)用talkWithDriver()
精簡(jiǎn)后的代碼如下:

status_t IPCThreadState::talkWithDriver(bool doReceive)
{
binder_write_read bwr;

// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();

// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();   /*****第1步*****/

// This is what we'll read.
if (doReceive && needRead) {
    bwr.read_size = mIn.dataCapacity();
    bwr.read_buffer = (uintptr_t)mIn.data();
} else {
    bwr.read_size = 0;
    bwr.read_buffer = 0;
}

// Return immediately if there is nothing to do.
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__)  /*****第2步*****/
    if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
        err = NO_ERROR;
    else
        err = -errno;
    #else
    err = INVALID_OPERATION;
    #endif
} while (err == -EINTR);                     

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

}

代碼看起來(lái)很長(zhǎng),但是其實(shí)主要就分為一下幾步,已在代碼中標(biāo)出:
1. 把數(shù)據(jù)包裝到一個(gè) ` binder_write_read` 結(jié)構(gòu)的變量 `bwr` 中
2. 調(diào)用 `ioctl` 向binder驅(qū)動(dòng)發(fā)送指令,binder驅(qū)動(dòng)會(huì)從 `bwr` 的 `write_buffer` 讀取數(shù)據(jù),經(jīng)過(guò)處理之后,如果有返回,就寫(xiě)入到 `read_buffer` 中
3. 根據(jù) `bwr` 中的數(shù)據(jù)更新 `mOut` 和 `mIn` 的數(shù)據(jù)

**注:**這里的第2步這里只是一筆帶過(guò),其實(shí)包含了和binder驅(qū)動(dòng)的交互的關(guān)鍵步驟,為了避免打斷分析的流程,這里就不深入了,具體可以參考 
[Android Binder機(jī)制(五) addService詳解01之 請(qǐng)求的發(fā)送](http://wangkuiwu.github.io/2014/09/05/BinderCommunication-AddService01/),
 [Android Binder機(jī)制(六) addService詳解02之 請(qǐng)求的處理](http://wangkuiwu.github.io/2014/09/05/BinderCommunication-AddService02/),
[Android Binder機(jī)制(七) addService詳解03之 請(qǐng)求的反饋](http://wangkuiwu.github.com/2014/09/05/BinderCommunication-AddService03/)
這三篇文章。這里我們只需要知道,binder驅(qū)動(dòng)把請(qǐng)求發(fā)送給 ServiceManager后,就返回了 BR_NOOP 和 BR_TRANSACTION_COMPLETE 兩條指令,注意這里返回時(shí)只代表驅(qū)動(dòng)已經(jīng)把請(qǐng)求發(fā)送給 ServiceManager處理,而處理的結(jié)果此時(shí)還沒(méi)返回。

####6.4.2 讀取 BR_NOOP 和 BR_TRANSACTION_COMPLETE
上一節(jié)第一次調(diào)用talkWithDriver()后,收到了binder驅(qū)動(dòng)返回的 BR_NOOP 和 BR_TRANSACTION_COMPLETE 兩條指令,回到`waitForResponse()`的死循環(huán),接著循環(huán)兩次從`mIn`中讀取兩條指令,這兩條指令都是什么都不做。

####6.4.3 進(jìn)入中斷等待
讀取完兩條返回的指令后,再次進(jìn)入 `waitForResponse()` 的死循環(huán),此時(shí):

bwr.write_size = 0;
bwr.write_buffer = (long unsigned int)mOut.data();
bwr.write_consumed = 0;
bwr.read_size = mIn.dataCapacity(); // 256字節(jié)
bwr.read_buffer = (long unsigned int)mIn.data();
bwr.read_consumed = 0;

再次進(jìn)入 talkWithDriver()->ioctl(),此時(shí)因?yàn)閎wr.write_size = 0 代表沒(méi)有數(shù)據(jù)要寫(xiě)入,然后bwr.read_consumed = 0 代表沒(méi)有數(shù)據(jù)要讀取,此時(shí)就會(huì)進(jìn)入中斷等待狀態(tài),具體查看 binder驅(qū)動(dòng)源碼中 binder_thread_read() 方法的實(shí)現(xiàn)。

###6.5 總結(jié)
概括起來(lái),向binder發(fā)起一個(gè)請(qǐng)求的過(guò)程主要包括:
1. 數(shù)據(jù)的層層封裝,Parcel --> binder_transaction_data --> binder_write_read
2. 通過(guò) IPCThreadState.transact() --> waitForResponse() --> talkWithDriver() --> ioctl() 向binder驅(qū)動(dòng)發(fā)起請(qǐng)求
3. binder驅(qū)動(dòng)會(huì)按照先寫(xiě)后讀的順序處理請(qǐng)求,喚醒服務(wù)端的進(jìn)程處理請(qǐng)求,同時(shí)向客戶端返回 BR_TRANSACTION_COMPLETE 代表已經(jīng)將客戶端的請(qǐng)求發(fā)送給服務(wù)端
4. 如果客戶端沒(méi)有別的請(qǐng)求,就陷入中斷等待
5. 服務(wù)端處理完請(qǐng)求,又將跟 binder 驅(qū)動(dòng)通訊,binder驅(qū)動(dòng)將喚醒客戶端,并把處理結(jié)果返回給客戶端

#7 The End
關(guān)于 binder 機(jī)制的整體流程的總結(jié)總算寫(xiě)完了,其中還涉及很多細(xì)節(jié)沒(méi)有涵蓋,不過(guò)作為一個(gè)備忘,起碼以后再看起來(lái),可以很快的理清思路,再需要找到實(shí)現(xiàn)細(xì)節(jié)也不難了。最后還是要感謝 [Android Binder機(jī)制系列文章](http://wangkuiwu.github.io/2014/09/01/Binder-Introduce/) 的作者,寫(xiě)的真是不能再詳細(xì)了!


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容