成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

干貨 | 徹底理解ANDROID BINDER通信架構(gòu)(下)

開發(fā) 開發(fā)工具
oneway與非oneway: 都是需要等待Binder Driver的回應(yīng)消息BR_TRANSACTION_COMPLETE. 主要區(qū)別在于oneway的通信收到BR_TRANSACTION_COMPLETE則返回,而不會再等待BR_REPLY消息的到來.

[[177275]]

2.10 IPC.waitForResponse

在這個(gè)過程中, 常見的幾個(gè)BR_命令:

  • BR_TRANSACTION_COMPLETE: binder驅(qū)動收到BC_TRANSACTION事件后的應(yīng)答消息; 對于oneway transaction,當(dāng)收到該消息,則完成了本次Binder通信;
  • BR_DEAD_REPLY: 回復(fù)失敗,往往是線程或節(jié)點(diǎn)為空. 則結(jié)束本次通信Binder;
  • BR_FAILED_REPLY:回復(fù)失敗,往往是transaction出錯(cuò)導(dǎo)致. 則結(jié)束本次通信Binder;
  • BR_REPLY: Binder驅(qū)動向Client端發(fā)送回應(yīng)消息; 對于非oneway transaction時(shí),當(dāng)收到該消息,則完整地完成本次Binder通信;

規(guī)律: BC_TRANSACTION + BC_REPLY = BR_TRANSACTION_COMPLETE + BR_DEAD_REPLY + BR_FAILED_REPLY

2.10.1 IPC.executeCommand

處于剩余的BR_命令.

2.11 IPC.talkWithDriver

binder_write_read結(jié)構(gòu)體用來與Binder設(shè)備交換數(shù)據(jù)的結(jié)構(gòu), 通過ioctl與mDriverFD通信,是真正與Binder驅(qū)動進(jìn)行數(shù)據(jù)讀寫交互的過程。 ioctl()方法經(jīng)過syscall最終調(diào)用到Binder_ioctl()方法.

三、Binder driver

3.1 binder_ioctl

[→ Binder.c]

由【小節(jié)2.11】傳遞過出來的參數(shù) cmd=BINDER_WRITE_READ

首先,根據(jù)傳遞過來的文件句柄指針獲取相應(yīng)的binder_proc結(jié)構(gòu)體, 再從中查找binder_thread,如果當(dāng)前線程已經(jīng)加入到proc的線程隊(duì)列則直接返回,如果不存在則創(chuàng)建binder_thread,并將當(dāng)前線程添加到當(dāng)前的proc.

  • 當(dāng)返回值為-ENOMEM,則意味著內(nèi)存不足,往往會出現(xiàn)創(chuàng)建binder_thread對象失敗;
  • 當(dāng)返回值為-EINVAL,則意味著CMD命令參數(shù)無效;

3.2 binder_ioctl_write_read

此時(shí)arg是一個(gè)binder_write_read結(jié)構(gòu)體,mOut數(shù)據(jù)保存在write_buffer,所以write_size>0,但此時(shí)read_size=0。首先,將用戶空間bwr結(jié)構(gòu)體拷貝到內(nèi)核空間,然后執(zhí)行binder_thread_write()操作.

3.3 binder_thread_write

不斷從binder_buffer所指向的地址獲取cmd, 當(dāng)只有BC_TRANSACTION或者BC_REPLY時(shí), 則調(diào)用binder_transaction()來處理事務(wù).

3.4 binder_transaction

發(fā)送的是BC_TRANSACTION時(shí),此時(shí)reply=0。

主要功能:

查詢目標(biāo)進(jìn)程的過程: handle → binder_ref → binder_node → binder_proc

將BINDER_WORK_TRANSACTION添加到目標(biāo)隊(duì)列target_list, ***發(fā)起事務(wù)則目標(biāo)隊(duì)列為target_proc->todo, reply事務(wù)時(shí)則為target_thread->todo; oneway的非reply事務(wù),則為target_node->async_todo.

將BINDER_WORK_TRANSACTION_COMPLETE添加到當(dāng)前線程的todo隊(duì)列此時(shí)當(dāng)前線程的todo隊(duì)列已經(jīng)有事務(wù), 接下來便會進(jìn)入binder_thread_read()來處理相關(guān)的事務(wù).

3.5 binder_thread_read

  • 當(dāng)收到的是BINDER_WORK_TRANSACTION_COMPLETE, 則將命令BR_TRANSACTION_COMPLETE寫回用戶空間.
  • 當(dāng)收到的是BINDER_WORK_TRANSACTION命令, 則將命令BR_TRANSACTION或BR_TRANSACTION寫回用戶空間.

四. 回到用戶空間

4.1 何去何從

  1. 執(zhí)行完binder_thread_write方法后, 通過binder_transaction()首先寫入BINDER_WORK_TRANSACTION_COMPLETE寫入當(dāng)前線程.
  2. 這時(shí)bwr.read_size > 0, 回到binder_ioctl_write_read方法, 便開始執(zhí)行binder_thread_read();
  3. 在binder_thread_read()方法, 將獲取cmd=BR_TRANSACTION_COMPLETE, 再將cmd和數(shù)據(jù)寫回用戶空間;
  4. 一次Binder_ioctl完成,接著回調(diào)用戶空間方法talkWithDriver(),并且剛才的數(shù)據(jù)寫入mIn.
  5. 這時(shí)mIn有可讀數(shù)據(jù), 回到waitForResponse()方法,完成BR_TRANSACTION_COMPLETE過程.
  6. 再回退到transact()方法, 對于oneway的操作, 這次Binder通信便完成, 否則還是要等待Binder服務(wù)端的返回.

對于startService過程, 顯然沒有指定oneway的方式,那么發(fā)起者進(jìn)程還會繼續(xù)停留在waitForResponse()方法,等待收到BR_REPLY消息. 由于在前面binder_transaction過程中,除了向自己所在線程寫入了BINDER_WORK_TRANSACTION_COMPLETE, 還向目標(biāo)進(jìn)程(此處為system_server)寫入了BINDER_WORK_TRANSACTION命令. 而此時(shí)system_server進(jìn)程的binder線程一旦空閑便是停留在binder_thread_read()方法來處理進(jìn)程/線程新的事務(wù), 收到的是BINDER_WORK_TRANSACTION命令, 經(jīng)過binder_thread_read()后生成命令BR_TRANSACTION.同樣的流程.

接下來,從system_server的binder線程一直的執(zhí)行流: IPC.joinThreadPool –> IPC.getAndExecuteCommand() → IPC.talkWithDriver() ,但talkWithDriver收到事務(wù)之后, 便進(jìn)入IPC.executeCommand(), 接下來,從executeCommand說起.

4.2 IPC.executeCommand

  • 對于oneway的場景, 則到此全部結(jié)束.
  • 對于非oneway, 也就是需要reply的通信過程,則向Binder驅(qū)動發(fā)送BC_REPLY命令

4.3 BBinder.transact

[→ Binder.cpp ::BBinder ]

4.4 JavaBBinder.onTransact

[→ android_util_Binder.cpp]

還記得AndroidRuntime::startReg過程嗎, 其中有一個(gè)過程便是register_android_os_Binder(),該過程會把gBinderOffsets.mExecTransact便是Binder.java中的execTransact()方法.詳見見Binder系列7—framework層分析文章中的第二節(jié)初始化的過程.

另外,此處mObject是在服務(wù)注冊addService過程,會調(diào)用writeStrongBinder方法, 將Binder對象傳入了JavaBBinder構(gòu)造函數(shù)的參數(shù), 最終賦值給mObject. 在本次通信過程中Object為ActivityManagerNative對象.

此處斗轉(zhuǎn)星移, 從C++代碼回到了Java代碼. 進(jìn)入AMN.execTransact, 由于AMN繼續(xù)于Binder對象, 接下來進(jìn)入Binder.execTransact

4.5 Binder.execTransact

[Binder.java]

當(dāng)發(fā)生RemoteException, RuntimeException, OutOfMemoryError, 對于非oneway的情況下都會把異常傳遞給調(diào)用者.

4.6 AMN.onTransact

[→ ActivityManagerNative.java]

4.7 AMS.startService

歷經(jīng)千山萬水, 總算是進(jìn)入了AMS.startService. 當(dāng)system_server收到BR_TRANSACTION的過程后, 再經(jīng)歷一個(gè)類似的過程,將事件告知app所在進(jìn)程service啟動完成.過程基本一致,此處就不再展開.

五. 總結(jié)

本文詳細(xì)地介紹如何從AMP.startService是如何通過Binder一步步調(diào)用進(jìn)入到system_server進(jìn)程的AMS.startService. 整個(gè)過程涉及Java framework, native, kernel driver各個(gè)層面知識. 僅僅一個(gè)Binder IPC調(diào)用, 就花費(fèi)了如此大篇幅來講解, 可見系統(tǒng)之龐大. 整個(gè)過程的調(diào)用流程:

5.1 通信流程

從通信流程角度來看整個(gè)過程:

前面第二至第四段落,主要講解過程 BC_TRANSACTION –> BR_TRANSACTION_COMPLETE –> BR_TRANSACTION.有興趣的同學(xué)可以再看看后面3個(gè)事務(wù)的處理:BC_REPLY –> BR_TRANSACTION_COMPLETE –> BR_REPLY,這兩個(gè)流程基本是一致的.

5.2 通信協(xié)議

從通信協(xié)議的角度來看這個(gè)過程:

  • Binder客戶端或者服務(wù)端向Binder Driver發(fā)送的命令都是以BC開頭,例如本文的BC_TRANSACTION和BC_REPLY, 所有Binder Driver向Binder客戶端或者服務(wù)端發(fā)送的命令則都是以BR開頭, 例如本文中的BR_TRANSACTION和BR_REPLY.
  • 只有當(dāng)BC_TRANSACTION或者BC_REPLY時(shí), 才調(diào)用binder_transaction()來處理事務(wù). 并且都會回應(yīng)調(diào)用者一個(gè)BINDER_WORK_TRANSACTION_COMPLETE事務(wù), 經(jīng)過binder_thread_read()會轉(zhuǎn)變成BR_TRANSACTION_COMPLETE.
  • startService過程便是一個(gè)非oneway的過程, 那么oneway的通信過程如下所述.

5.3 說一說oneway

上圖是非oneway通信過程的協(xié)議圖, 下圖則是對于oneway場景下的通信協(xié)議圖:

當(dāng)收到BR_TRANSACTION_COMPLETE則程序返回,有人可能覺得好奇,為何oneway怎么還要等待回應(yīng)消息? 我舉個(gè)例子,你就明白了.

你(app進(jìn)程)要給遠(yuǎn)方的家人(system_server進(jìn)程)郵寄一封信(transaction), 你需要通過郵寄員(Binder Driver)來完成.整個(gè)過程如下:

  1. 你把信交給郵寄員(BC_TRANSACTION);
  2. 郵寄員收到信后, 填一張單子給你作為一份回執(zhí)(BR_TRANSACTION_COMPLETE). 這樣你才放心知道郵遞員已確定接收信, 否則就這樣走了,信到底有沒有交到郵遞員手里都不知道,這樣的通信實(shí)在太讓人不省心, 長時(shí)間收不到遠(yuǎn)方家人的回信, 無法得知是在路的中途信件丟失呢,還是壓根就沒有交到郵遞員的手里. 所以說oneway也得知道信是投遞狀態(tài)是否成功.
  3. 郵遞員利用交通工具(Binder Driver),將信交給了你的家人(BR_TRANSACTION);當(dāng)你收到回執(zhí)(BR_TRANSACTION_COMPLETE)時(shí)心里也不期待家人回信, 那么這便是一次oneway的通信過程.

如果你希望家人回信, 那便是非oneway的過程,在上述步驟2后并不是直接返回,而是繼續(xù)等待著收到家人的回信, 經(jīng)歷前3個(gè)步驟之后繼續(xù)執(zhí)行:

  1. 家人收到信后, 立馬寫了個(gè)回信交給郵遞員BC_REPLY;
  2. 同樣,郵遞員要寫一個(gè)回執(zhí)(BR_TRANSACTION_COMPLETE)給你家人;
  3. 郵遞員再次利用交通工具(Binder Driver), 將回信成功交到你的手上(BR_REPLY)這便是一次完成的非oneway通信過程.

oneway與非oneway: 都是需要等待Binder Driver的回應(yīng)消息BR_TRANSACTION_COMPLETE. 主要區(qū)別在于oneway的通信收到BR_TRANSACTION_COMPLETE則返回,而不會再等待BR_REPLY消息的到來.

【本文是51CTO專欄“小米開放平臺”原創(chuàng)文章,“小米開放平臺”微信公眾號xiaomideveloper】

 

責(zé)任編輯:武曉燕 來源: 小米開放平臺
相關(guān)推薦

2016-11-28 14:11:24

ANDROID BIN通信架構(gòu)

2021-05-13 08:55:33

Android架構(gòu)功能

2019-01-09 08:31:07

2020-10-27 12:02:46

VMware vSph虛擬卷vVols

2018-02-26 16:07:48

Android3DDepth

2021-09-07 08:49:35

Android

2021-09-04 07:29:57

Android

2021-08-15 08:11:54

AndroidSynchronize關(guān)鍵字

2019-11-07 10:37:36

CookieSessionToken

2020-03-03 14:15:49

Redis持久化數(shù)據(jù)庫

2019-06-11 14:45:25

2024-03-15 08:23:26

異步編程函數(shù)

2023-11-08 07:39:42

2024-11-25 16:39:17

2019-12-10 13:55:10

Go指針存儲

2023-12-28 10:39:57

數(shù)組節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu)

2023-01-06 08:42:41

動態(tài)規(guī)劃字符

2022-10-24 08:08:27

閉包編譯器

2021-12-27 09:33:12

內(nèi)存泄漏程序

2010-03-04 09:46:51

Android Bin
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 狠狠爱综合 | 国产精品不卡 | 国产色婷婷精品综合在线手机播放 | 久久免费大片 | 久久久精品一区二区三区四季av | 一区二区三区高清 | 99精品欧美一区二区蜜桃免费 | 欧美日韩免费一区二区三区 | 波多野结衣一区二区三区在线观看 | 久草中文在线 | 亚洲精品久久久一区二区三区 | 亚洲欧洲中文 | 国产精品久久久久一区二区 | 99久久亚洲 | 性做久久久久久免费观看欧美 | 久久天堂网 | 国产综合视频 | 91手机精品视频 | 一区二区三区视频 | 欧美中文字幕在线观看 | 成人片免费看 | 龙珠z在线观看 | 亚洲最大av网站 | 亚洲高清在线观看 | 久久久毛片 | 91视频免费黄 | 欧美成人黄色小说 | 亚洲视频一区二区三区四区 | 精品国产一区二区三区久久久久久 | 久久久激情 | 日韩中文字幕免费在线 | 欧美精品v | 国产精品久久久久久妇女6080 | 国产区在线看 | 视频一二三区 | 亚洲欧美中文字幕在线观看 | 国产精品高潮呻吟久久久久 | 国产一区二区三区色淫影院 | 久久久久久久久久久成人 | 毛片免费观看 | av在线一区二区三区 |