Android ServiceManager的啟動(dòng)和工作原理
所有的系統(tǒng)服務(wù)都是需要在ServiceManager中進(jìn)行注冊(cè)的,而ServiceManager作為一個(gè)起始的服務(wù),是通過(guò)init.rc來(lái)啟動(dòng)的。
//systemcorerootdirinit.rc//啟動(dòng)的服務(wù),這里是用的服務(wù)名稱(chēng)。服務(wù)名稱(chēng)是在對(duì)應(yīng)的rc文件中注冊(cè)并啟動(dòng)的 start servicemanager
具體的服務(wù)信息是在servicemanger.rc命名并定義的
//frameworksnativecmdsservicemanagerservicemanager.rcservice servicemanager /system/bin/servicemanager class core animation user system //說(shuō)明以用戶(hù)system身份運(yùn)行 group system readproc //說(shuō)明servicemanager是系統(tǒng)中的關(guān)鍵服務(wù), //關(guān)鍵服務(wù)是不會(huì)退出的,如果退出了,系統(tǒng)就會(huì)重啟,當(dāng)系統(tǒng)重啟時(shí)就會(huì)啟動(dòng)用onrestart關(guān)鍵字修飾的進(jìn)程, //比如zygote、media、surfaceflinger等等。 critical onrestart restart healthd onrestart restart zygote onrestart restart audioserver onrestart restart media onrestart restart surfaceflinger onrestart restart inputflinger onrestart restart drm onrestart restart cameraserver onrestart restart keystore onrestart restart gatekeeperd onrestart restart thermalservice ..
servicemanager的入口函數(shù)在service_manager.c中
//frameworksnativelibsbinderndkservice_manager.cppint main(int argc, char** argv){//binder_state結(jié)構(gòu)體,用來(lái)存儲(chǔ)binder的三個(gè)信息 struct binder_state *bs;//打開(kāi)binder驅(qū)動(dòng),并申請(qǐng)125k字節(jié)的內(nèi)存空間 bs = binder_open(driver, 128*1024); ...//將自己注冊(cè)為Binder機(jī)制的管理者 if (binder_become_context_manager(bs)) { ALOGE('cannot become context manager (%s)n', strerror(errno)); return -1; } ...//啟動(dòng)循環(huán),等待并處理client端發(fā)來(lái)的請(qǐng)求 binder_loop(bs, svcmgr_handler); return 0;}
在main函數(shù)中主要做了3件事情。
打開(kāi)驅(qū)動(dòng),并申請(qǐng)了128k字節(jié)大小的內(nèi)存空間 將自己注冊(cè)為Binder機(jī)制的管理者 啟動(dòng)循環(huán),等待并處理Client端發(fā)來(lái)的請(qǐng)求 binder_open//frameworksnativecmdsservicemanagerbinder.cstruct binder_state *binder_open(const char* driver, size_t mapsize){ struct binder_state *bs; struct binder_version vers; //申請(qǐng)對(duì)應(yīng)的內(nèi)存空間 bs = malloc(sizeof(*bs));//打開(kāi)binder設(shè)備文件,這種屬于設(shè)備驅(qū)動(dòng)的操作方法 bs->fd = open(driver, O_RDWR | O_CLOEXEC);//通過(guò)ioctl獲取binder的版本號(hào) if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) || (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) { fprintf(stderr,'binder: kernel driver version (%d) differs from user space version (%d)n',vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION); goto fail_open; } bs->mapsize = mapsize;//mmap進(jìn)行內(nèi)存映射,將Binder設(shè)備文件映射到進(jìn)程的對(duì)應(yīng)地址空間,地址空間大小為128k//映射之后,會(huì)將地址空間的起始地址和大小保存到結(jié)構(gòu)體中, bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); return bs;}
binder_opende的主要功能是打開(kāi)了Binder的驅(qū)動(dòng)文件,并將文件進(jìn)行了mmap映射,并將對(duì)應(yīng)的地址空間保存到了結(jié)構(gòu)體中。
binder_become_context_manager//frameworksnativecmdsservicemanagerbinder.cint binder_become_context_manager(struct binder_state *bs){ return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);}
ioctl會(huì)調(diào)用Binder驅(qū)動(dòng)的binder_ioctl函數(shù),去注冊(cè)成為管理者。
binder_loop將servicemanger注冊(cè)為Binder的上下文管理者后,它就是Binder機(jī)制的“大總管”了,它會(huì)在系統(tǒng)運(yùn)行期間處理Client端的請(qǐng)求,因?yàn)檎?qǐng)求的時(shí)間不確定性,這里采用了無(wú)限循環(huán)來(lái)實(shí)現(xiàn)。也就是binder_loop
//frameworksnativecmdsservicemanagerbinder.cvoid binder_loop(struct binder_state *bs, binder_handler func){ int res; struct binder_write_read bwr; uint32_t readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0;//當(dāng)前線(xiàn)程注冊(cè)為Binder的指令 readbuf[0] = BC_ENTER_LOOPER;//將BC_ENTER_LOOPER指令寫(xiě)入到Binder驅(qū)動(dòng),//將當(dāng)前的ServiceManager線(xiàn)程注冊(cè)為了一個(gè)Binder線(xiàn)程(注意ServiceManager本身也是一個(gè)Binder線(xiàn)程)。//注冊(cè)為Binder線(xiàn)程之后,就可以處理進(jìn)程間的請(qǐng)求了 binder_write(bs, readbuf, sizeof(uint32_t));//不斷的循環(huán)遍歷 for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (uintptr_t) readbuf;//使用BINDER_WRITE_READ指令查詢(xún)Binder驅(qū)動(dòng)中是否有請(qǐng)求。//如果有請(qǐng)求,就走到下面的binder_parse部分處理,如果沒(méi)有,當(dāng)前的ServiceManager線(xiàn)程就會(huì)在Binder驅(qū)動(dòng)中水命,等待新的進(jìn)程間請(qǐng)求 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//走到這里說(shuō)明有請(qǐng)求信息。將請(qǐng)求的信息用binder_parse來(lái)處理,處理方法是func res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); }}
servicemanager會(huì)先將自己注冊(cè)為一個(gè)Binder線(xiàn)程。因?yàn)橹挥凶?cè)成為Binder服務(wù)之后才能接收進(jìn)程間的請(qǐng)求。而注冊(cè)為Binder服務(wù)的指令是BC_ENTER_LOOPER。然后通過(guò)**binder_write()**方法寫(xiě)入到binder驅(qū)動(dòng)。
//frameworksnativecmdsservicemanagerbinder.cint binder_write(struct binder_state *bs, void *data, size_t len){ struct binder_write_read bwr; int res; bwr.write_size = len; bwr.write_consumed = 0; bwr.write_buffer = (uintptr_t) data; bwr.read_size = 0; bwr.read_consumed = 0; bwr.read_buffer = 0;//BINDER_WRITE_READ既可以讀也可以寫(xiě)。關(guān)鍵在于read_size和write_size。//如果write_size>0。則是寫(xiě)。如果read_size>0則是讀。//如果都大于0,則先寫(xiě),再讀 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0) { fprintf(stderr,'binder_write: ioctl failed (%s)n',strerror(errno)); } return res;}系統(tǒng)服務(wù)注冊(cè)
在Android中,每個(gè)進(jìn)程獲取系統(tǒng)提供的各種系統(tǒng)服務(wù)(AMS,PMS,WMS等)都是需要通過(guò)ServiceManager才可以。而這些系統(tǒng)服務(wù)進(jìn)行Binder注冊(cè),也需要獲取ServiceManager服務(wù)才可以。在剛才我們講過(guò),ServiceManager會(huì)將自己也注冊(cè)成為一個(gè)Binder服務(wù)。
這里我們以SurfaceFling獲取ServiceManager服務(wù)為例來(lái)看一下是如何獲取的。
//frameworksnativeservicessurfaceflingermain_surfaceflinger.cpp#include <binder/IServiceManager.h>int main(int, char**) { .... //獲取一個(gè)SM對(duì)象,相當(dāng)于是new BpServiceManager(new BpBinder(0)) sp<IServiceManager> sm(defaultServiceManager());//向ServiceManager注冊(cè)SurfaceFling服務(wù) sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);//在SurfaceFlinger調(diào)用init方法的時(shí)候,會(huì)初始化Display的相關(guān)信息 startDisplayService(); // dependency on SF getting registered above ... return 0;}
系統(tǒng)服務(wù)的注冊(cè)過(guò)程主要有2點(diǎn)
獲取ServiceManager所對(duì)應(yīng)的Binder對(duì)象。 通過(guò)addService注冊(cè)為系統(tǒng)服務(wù)。 ServiceManager的Binder對(duì)象獲取**defaultServiceManager()**方法就是用來(lái)獲取ServiceManager服務(wù)的Binder對(duì)象。
defaultServiceManager
//frameworksnativelibsbinderIServiceManager.cppsp<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != nullptr) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock);/* * 1. ProcessState::self()->getContextObject(NULL): 返回的是一個(gè) BpBinder. ServiceManager 的 desc 默認(rèn)為0. * 2. interface_cast 就是將 BpBinder 封裝為 IServiceManager,這樣可以直接調(diào)用 IServiceManager 的接口.*//* * 這里,有一個(gè)設(shè)計(jì)思想. * 1. defaultServiceManager 首先實(shí)例化 BpBinder. * 2. interface_cast 就是 實(shí)例化 BpXXX,并將 BpBinder 交給其管理. * * Proxy 端的用戶(hù)無(wú)法直接看到 BpBinder , BpBinder 由 BpXXX 持有.用戶(hù)本身不關(guān)心 BpBinder 的能力,只關(guān)心 IXXX 定義的 接口. * 所以這里很好的進(jìn)行了封裝.*/ while (gDefaultServiceManager == nullptr) {//如果不為空,表示設(shè)置過(guò)了,直接返回 //嘗試不斷的獲取ServiceManager對(duì)象,如果獲取不到,就sleep(1), //這里之所以會(huì)獲取不到,是因?yàn)镾erviceManager和一些通過(guò)init.rc啟動(dòng)的服務(wù)是同時(shí)啟動(dòng)的,不能保證ServiceManager能夠優(yōu)先啟動(dòng)完成。 //所以會(huì)存在獲取ServiceManager的時(shí)候獲取不到。 gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(nullptr)); if (gDefaultServiceManager == nullptr)sleep(1); } } return gDefaultServiceManager;}
這里會(huì)直接調(diào)用**ProcessState::self()->getContextObject(nullptr)**來(lái)獲取對(duì)應(yīng)的服務(wù)。
ProcessState::self()->getContextObject(NULL): 返回的是一個(gè) BpHwBinder。ServiceManager 的 desc 默認(rèn)為0。 interface_cast 就是將 BpBinder 封裝為 IServiceManagerProcessState::self()
//systemlibhwbinderProcessState.cpp//返回一個(gè)ProcessStatesp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != nullptr) { return gProcess; } gProcess = new ProcessState(kDefaultDriver); return gProcess;}
這里會(huì)返回一個(gè)ProcessState對(duì)象。
getContextObject
//systemlibhwbinderProcessState.cppsp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){ //傳入的參數(shù)是handle。0, return getStrongProxyForHandle(0);}sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){ handle_entry* e = lookupHandleLocked(handle); if (e != nullptr) { IBinder* b = e->binder; if (b == nullptr || !e->refs->attemptIncWeak(this)) {//如果b為空,那么創(chuàng)建一個(gè)BpHwBinder b = new BpHwBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } } return result;}
當(dāng)不存在的時(shí)候,這里會(huì)創(chuàng)建一個(gè)BpHwBinder對(duì)象。所以可以理解為最后我們返回的是一個(gè)BpBinder對(duì)象
這里,有一個(gè)設(shè)計(jì)思想:
defaultServiceManager 首先實(shí)例化 BpBinder。 interface_cast 就是 實(shí)例化 BpXXX,并將 BpBinder交給其管理。Proxy 端的用戶(hù)無(wú)法直接看到 BpBinder, BpBinder 由 BpXXX 持有.用戶(hù)本身不關(guān)心 BpBinder的能力,只關(guān)心 IXXX 定義的 接口。所以這里很好的進(jìn)行了封裝。
回到前文的defaultServiceManger方法中,將返回值帶入,可以得到
//注意,方法中傳入的handle為0,所以BpBinder參數(shù)為0gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
interface_cast
//frameworksnativeincludebinderIInterface.hinline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}//INTERFACE帶入為IServiceManager之后,得到的代碼為inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){ return IServiceManager::asInterface(obj);//靜態(tài)方法所以直接調(diào)用}
調(diào)用IServiceManager接口的成員函數(shù)asInterface,將一個(gè)句柄值為0的Binder代理對(duì)象封裝為一個(gè)ServiceManger代理對(duì)象。將一個(gè)句柄值為0的Binder代理對(duì)象封裝為一個(gè)ServiceManger代理對(duì)象。
這里 IServiceManager接口的成員函數(shù)asInterface是通過(guò)宏IMPLEMENT_META_INTERFACE實(shí)現(xiàn),如下所示:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) #endif#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) ::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; }
帶入IServiceManager之后的代碼為:
android::sp<IServiceManager> IIServiceManager::asInterface(const android::sp<android::IBinder>& obj) { android::sp<IServiceManager> intr; if (obj != NULL) { intr = static_cast<IIServiceManager*>( obj->queryLocalInterface(IServiceManager::descriptor).get());//返回NULLif (intr == NULL) {intr = new BpServiceManager(obj); //創(chuàng)建了ServiceManager代理對(duì)象 } }return intr; }
到這里為止,我們創(chuàng)建了一個(gè)BpIServiceManager對(duì)象,并將他的接口IServiceManager返回給了調(diào)用者。
整體的邏輯可以理解為:new BpServiceManager(new BpBinder())。當(dāng)然了,這只是簡(jiǎn)化之后的代碼,其內(nèi)部復(fù)雜的邏輯現(xiàn)在可以暫不考慮。整體流程如下:
客戶(hù)端請(qǐng)求
當(dāng)獲取到ServiceManager服務(wù)之后,就可以使用addService方法來(lái)進(jìn)行服務(wù)的注冊(cè)了。在獲取服務(wù)的時(shí)候,最終返回的是BpServiceManager對(duì)象,所以這里我們可以直接找到對(duì)應(yīng)的添加服務(wù)方法
virtual status_t addService(const String16& name, const sp<IBinder>& service,bool allowIsolated, int dumpsysPriority) { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); data.writeInt32(dumpsysPriority); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err; }
BpServiceManager的構(gòu)造函數(shù)傳入的了BpBinder對(duì)象,這里的remote()方法其實(shí)就是BpBinder對(duì)象。
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ //如果binder已經(jīng)died,則不會(huì)返回?cái)?shù)據(jù) if (mAlive) { ...//調(diào)用IPCThreadState的transact方法。 status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT;}
這里調(diào)用了IPCThreadState的transact方法將對(duì)應(yīng)的數(shù)據(jù)寫(xiě)入到了Binder驅(qū)動(dòng)了。當(dāng)Binder驅(qū)動(dòng)接收到注冊(cè)服務(wù)的信息的時(shí)候,就會(huì)將對(duì)應(yīng)的服務(wù)注冊(cè)到ServiceManager中。我們可以看下傳遞的參數(shù):
mHandle:0,表示要處理該請(qǐng)求的進(jìn)程號(hào),ServiceManager在注冊(cè)的時(shí)候,其對(duì)應(yīng)的進(jìn)程號(hào)是0。所以處理請(qǐng)求的也就是ServiceManager進(jìn)程。 code:參數(shù)是ADD_SERVICE_TRANSACTION。 data:包含了要添加的進(jìn)程相關(guān)信息:包括名稱(chēng)、是否單獨(dú)運(yùn)行等等相關(guān)信息ServiceManager處理請(qǐng)求
當(dāng)客戶(hù)端發(fā)送請(qǐng)求之后,我們的ServiceManger就可以接收到消息,并且進(jìn)行消息的處理了。在ServiceManager的啟動(dòng)中我們了解到,當(dāng)ServiceManger啟動(dòng)之后,會(huì)調(diào)用binder_looper來(lái)不斷的循環(huán),檢測(cè)是否接收到對(duì)應(yīng)的數(shù)據(jù)信息。
這個(gè)功能是在binder_loop()方法的入?yún)⒅械膕vcmgr_handler來(lái)實(shí)現(xiàn)的。
//frameworksnativelibsbinderndkservice_manager.cppint main(int argc, char** argv){...//啟動(dòng)循環(huán),等待并處理client端發(fā)來(lái)的請(qǐng)求 binder_loop(bs, svcmgr_handler); ...}
svcmgr_handler就是我們具體的請(qǐng)求處理方法。
//frameworksnativecmdsservicemanagerservice_manager.cint svcmgr_handler(struct binder_state *bs, struct binder_transaction_data_secctx *txn_secctx, struct binder_io *msg, struct binder_io *reply){ ... struct binder_transaction_data *txn = &txn_secctx->transaction_data; ...//根據(jù)傳輸?shù)牟煌?lèi)型來(lái)進(jìn)行處理。 switch(txn->code) { case SVC_MGR_ADD_SERVICE://添加服務(wù) //進(jìn)行服務(wù)的添加 do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,txn->sender_pid, (const char*) txn_secctx->secctx) ... } int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid, const char* sid) { struct svcinfo *si; //ALOGI('add_service(’%s’,%x,%s) uid=%dn', str8(s, len), handle, // allow_isolated ? 'allow_isolated' : '!allow_isolated', uid); //服務(wù)的名稱(chēng)長(zhǎng)度不能超過(guò)127字節(jié) if (!handle || (len == 0) || (len > 127)) return -1;//最終調(diào)用selinux_check_access方法,會(huì)進(jìn)行權(quán)限的檢測(cè),檢查服務(wù)是否有進(jìn)行服務(wù)注冊(cè) if (!svc_can_register(s, len, spid, sid, uid)) { ALOGE('add_service(’%s’,%x) uid=%d - PERMISSION DENIEDn', str8(s, len), handle, uid); return -1; }//查詢(xún)是否已經(jīng)有包含了name的svcinfo si = find_svc(s, len); if (si) { if (si->handle) { ALOGE('add_service(’%s’,%x) uid=%d - ALREADY REGISTERED, OVERRIDEn', str8(s, len), handle, uid);//已經(jīng)注冊(cè)了,釋放相應(yīng)的服務(wù) svcinfo_death(bs, si); }//更新服務(wù)的handle si->handle = handle; } else {//申請(qǐng)內(nèi)存 si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t)); si->handle = handle; si->len = len; memcpy(si->name, s, (len + 1) * sizeof(uint16_t)); si->name[len] = ’0’; si->death.func = (void*) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->dumpsys_priority = dumpsys_priority;//將其注冊(cè)到服務(wù)列表svclist中,這里使用的鏈表來(lái)保存數(shù)據(jù) si->next = svclist; svclist = si; }//以handle為目標(biāo),發(fā)送BC_ACQUIRE指令。 binder_acquire(bs, handle);//以handle為目標(biāo),發(fā)送BC_REQUEST_DEATH_NOTIFICATION指令。 binder_link_to_death(bs, handle, &si->death); return 0;}
當(dāng)拿到請(qǐng)求信息之后,ServiceManager會(huì)生成對(duì)應(yīng)的svcinfo對(duì)象,將其保存到服務(wù)列表svclist中。
整體流程如下:
我們也可以從另一個(gè)維度去看看Binder的具體
系統(tǒng)服務(wù)獲取對(duì)于Servie服務(wù)的獲取,其實(shí)也是答題思路也是相同的。顯示獲取ServiceManager的Binder對(duì)象,然后服務(wù)端發(fā)送獲取某項(xiàng)服務(wù)的請(qǐng)求,ServiceManager來(lái)進(jìn)行處理。
這里我們只看一下ServiceManager接收到服務(wù)獲取的處理機(jī)制。也是在**svcmgr_handler()**中。
//frameworksnativecmdsservicemanagerservice_manager.cint svcmgr_handler(struct binder_state *bs, struct binder_transaction_data_secctx *txn_secctx, struct binder_io *msg, struct binder_io *reply){ ... struct binder_transaction_data *txn = &txn_secctx->transaction_data; ...//根據(jù)傳輸?shù)牟煌?lèi)型來(lái)進(jìn)行處理。 switch(txn->code) { case SVC_MGR_GET_SERVICE://獲取服務(wù) case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) {return -1; } //根據(jù)pid,uid來(lái)獲取服務(wù)對(duì)應(yīng)的handle值 handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid, (const char*) txn_secctx->secctx); if (!handle)break; //返回服務(wù)對(duì)應(yīng)的handle bio_put_ref(reply, handle); return 0;}
這里主要做了2個(gè)操作:
從服務(wù)列表中獲取到對(duì)應(yīng)的服務(wù)的handle 將handle寫(xiě)入到要返回的reply數(shù)據(jù)中。 do_find_service//frameworksnativecmdsservicemanagerservice_manager.c //獲取對(duì)應(yīng)的服務(wù)uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid, const char* sid){//獲取對(duì)應(yīng)的服務(wù) struct svcinfo *si = find_svc(s, len); if (!si || !si->handle) { return 0; } if (!si->allow_isolated) { // If this service doesn’t allow access from isolated processes, // then check the uid to see if it is isolated. uid_t appid = uid % AID_USER;//檢查服務(wù)是否是允許孤立于進(jìn)程而單獨(dú)存在的 if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) { return 0; } }//檢測(cè)是否有selinx權(quán)限。 if (!svc_can_find(s, len, spid, sid, uid)) { return 0; }//返回服務(wù)的handle return si->handle;}bio_put_ref
當(dāng)獲取到服務(wù)之后handle之后,會(huì)調(diào)用**bio_put_ref()**方法將服務(wù)對(duì)應(yīng)的handle寫(xiě)入到返回的數(shù)據(jù)中。
//frameworksnativecmdsservicemanagerservice_manager.cvoid bio_put_ref(struct binder_io *bio, uint32_t handle){ struct flat_binder_object *obj;//申請(qǐng)對(duì)應(yīng)的地址空間 if (handle) obj = bio_alloc_obj(bio); else obj = bio_alloc(bio, sizeof(*obj)); if (!obj) return; obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;//類(lèi)型是BINDER_TYPE_HANDLE obj->hdr.type = BINDER_TYPE_HANDLE;//記錄handle obj->handle = handle; obj->cookie = 0;}
對(duì)于服務(wù)的獲取,肯定是需要將reply的數(shù)據(jù)寫(xiě)回到請(qǐng)求服務(wù)的進(jìn)程的。這時(shí)候就需要回到我們?cè)赽inder_loop()函數(shù)了。在該函數(shù)中,存在一個(gè)binder_parse(),在這個(gè)方法里面會(huì)處理請(qǐng)求信息,并將reply信息通過(guò)binder驅(qū)動(dòng)發(fā)送給客戶(hù)端。
binder_parse//frameworksnativecmdsservicemanagerbinder.cint binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func){ ... case BR_TRANSACTION: { ...//調(diào)用func函數(shù)res = func(bs, txn, &msg, &reply);if (txn->flags & TF_ONE_WAY) { binder_free_buffer(bs, txn->data.ptr.buffer);} else {//發(fā)送協(xié)議指令給Binder驅(qū)動(dòng),向Client端發(fā)送reply binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);} ... return r;}
當(dāng)調(diào)用了func函數(shù),有對(duì)應(yīng)返回信息之后,會(huì)通過(guò)binder_send_reply()方法,將reply數(shù)據(jù)信息發(fā)送給client端。
void binder_send_reply(struct binder_state *bs, struct binder_io *reply, binder_uintptr_t buffer_to_free, int status){ struct { uint32_t cmd_free; binder_uintptr_t buffer; uint32_t cmd_reply; struct binder_transaction_data txn; } __attribute__((packed)) data; data.cmd_free = BC_FREE_BUFFER; data.buffer = buffer_to_free;//返回指令 data.cmd_reply = BC_REPLY; data.txn.target.ptr = 0; data.txn.cookie = 0; data.txn.code = 0; if (status) { data.txn.flags = TF_STATUS_CODE; data.txn.data_size = sizeof(int); data.txn.offsets_size = 0; data.txn.data.ptr.buffer = (uintptr_t)&status; data.txn.data.ptr.offsets = 0; } else {//svcmgr_handler執(zhí)行成功,將reply數(shù)據(jù)組裝到txn中 data.txn.flags = 0; data.txn.data_size = reply->data - reply->data0; data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0); data.txn.data.ptr.buffer = (uintptr_t)reply->data0; data.txn.data.ptr.offsets = (uintptr_t)reply->offs0; }//發(fā)送數(shù)據(jù) binder_write(bs, &data, sizeof(data));}總結(jié)
ServiceManager是一個(gè)守護(hù)進(jìn)程,負(fù)責(zé)管理系統(tǒng)中的所有服務(wù)信息。通過(guò)一個(gè)鏈表來(lái)保存了所有注冊(cè)過(guò)的信息。而且其本身也是一個(gè)服務(wù),在通過(guò)Binder驅(qū)動(dòng)將其注冊(cè)為守護(hù)進(jìn)程之后,會(huì)將自己也注冊(cè)為一個(gè)服務(wù),供其他服務(wù)調(diào)用。
以上就是Android ServiceManager的啟動(dòng)和工作原理的詳細(xì)內(nèi)容,更多關(guān)于Android ServiceManager的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. ASP新手必備的基礎(chǔ)知識(shí)2. .NET 中配置從xml轉(zhuǎn)向json方法示例詳解3. 微信小程序?qū)崿F(xiàn)商品分類(lèi)頁(yè)過(guò)程結(jié)束4. vue-electron中修改表格內(nèi)容并修改樣式5. 推薦一個(gè)好看Table表格的css樣式代碼詳解6. ASP常用日期格式化函數(shù) FormatDate()7. 利用FastReport傳遞圖片參數(shù)在報(bào)表上展示簽名信息的實(shí)現(xiàn)方法8. phpstudy apache開(kāi)啟ssi使用詳解9. HTML中的XML數(shù)據(jù)島記錄編輯與添加10. 以PHP代碼為實(shí)例詳解RabbitMQ消息隊(duì)列中間件的6種模式
