久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

Android ServiceManager的啟動和工作原理

瀏覽:2日期:2022-09-20 09:27:11
ServiceManager啟動

所有的系統(tǒng)服務(wù)都是需要在ServiceManager中進(jìn)行注冊的,而ServiceManager作為一個起始的服務(wù),是通過init.rc來啟動的。

//systemcorerootdirinit.rc//啟動的服務(wù),這里是用的服務(wù)名稱。服務(wù)名稱是在對應(yīng)的rc文件中注冊并啟動的 start servicemanager

具體的服務(wù)信息是在servicemanger.rc命名并定義的

//frameworksnativecmdsservicemanagerservicemanager.rcservice servicemanager /system/bin/servicemanager class core animation user system //說明以用戶system身份運(yùn)行 group system readproc //說明servicemanager是系統(tǒng)中的關(guān)鍵服務(wù), //關(guān)鍵服務(wù)是不會退出的,如果退出了,系統(tǒng)就會重啟,當(dāng)系統(tǒ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)體,用來存儲binder的三個信息 struct binder_state *bs;//打開binder驅(qū)動,并申請125k字節(jié)的內(nèi)存空間 bs = binder_open(driver, 128*1024); ...//將自己注冊為Binder機(jī)制的管理者 if (binder_become_context_manager(bs)) { ALOGE('cannot become context manager (%s)n', strerror(errno)); return -1; } ...//啟動循環(huán),等待并處理client端發(fā)來的請求 binder_loop(bs, svcmgr_handler); return 0;}

在main函數(shù)中主要做了3件事情。

打開驅(qū)動,并申請了128k字節(jié)大小的內(nèi)存空間 將自己注冊為Binder機(jī)制的管理者 啟動循環(huán),等待并處理Client端發(fā)來的請求 binder_open

//frameworksnativecmdsservicemanagerbinder.cstruct binder_state *binder_open(const char* driver, size_t mapsize){ struct binder_state *bs; struct binder_version vers; //申請對應(yīng)的內(nèi)存空間 bs = malloc(sizeof(*bs));//打開binder設(shè)備文件,這種屬于設(shè)備驅(qū)動的操作方法 bs->fd = open(driver, O_RDWR | O_CLOEXEC);//通過ioctl獲取binder的版本號 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)程的對應(yīng)地址空間,地址空間大小為128k//映射之后,會將地址空間的起始地址和大小保存到結(jié)構(gòu)體中, bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); return bs;}

binder_opende的主要功能是打開了Binder的驅(qū)動文件,并將文件進(jìn)行了mmap映射,并將對應(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會調(diào)用Binder驅(qū)動的binder_ioctl函數(shù),去注冊成為管理者。

binder_loop

將servicemanger注冊為Binder的上下文管理者后,它就是Binder機(jī)制的“大總管”了,它會在系統(tǒng)運(yùn)行期間處理Client端的請求,因?yàn)檎埱蟮臅r間不確定性,這里采用了無限循環(huán)來實(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)前線程注冊為Binder的指令 readbuf[0] = BC_ENTER_LOOPER;//將BC_ENTER_LOOPER指令寫入到Binder驅(qū)動,//將當(dāng)前的ServiceManager線程注冊為了一個Binder線程(注意ServiceManager本身也是一個Binder線程)。//注冊為Binder線程之后,就可以處理進(jìn)程間的請求了 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指令查詢Binder驅(qū)動中是否有請求。//如果有請求,就走到下面的binder_parse部分處理,如果沒有,當(dāng)前的ServiceManager線程就會在Binder驅(qū)動中水命,等待新的進(jìn)程間請求 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//走到這里說明有請求信息。將請求的信息用binder_parse來處理,處理方法是func res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); }}

servicemanager會先將自己注冊為一個Binder線程。因?yàn)橹挥凶猿蔀锽inder服務(wù)之后才能接收進(jìn)程間的請求。而注冊為Binder服務(wù)的指令是BC_ENTER_LOOPER。然后通過**binder_write()**方法寫入到binder驅(qū)動。

//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既可以讀也可以寫。關(guān)鍵在于read_size和write_size。//如果write_size>0。則是寫。如果read_size>0則是讀。//如果都大于0,則先寫,再讀 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ù)注冊

在Android中,每個進(jìn)程獲取系統(tǒng)提供的各種系統(tǒng)服務(wù)(AMS,PMS,WMS等)都是需要通過ServiceManager才可以。而這些系統(tǒng)服務(wù)進(jìn)行Binder注冊,也需要獲取ServiceManager服務(wù)才可以。在剛才我們講過,ServiceManager會將自己也注冊成為一個Binder服務(wù)。

這里我們以SurfaceFling獲取ServiceManager服務(wù)為例來看一下是如何獲取的。

//frameworksnativeservicessurfaceflingermain_surfaceflinger.cpp#include <binder/IServiceManager.h>int main(int, char**) { .... //獲取一個SM對象,相當(dāng)于是new BpServiceManager(new BpBinder(0)) sp<IServiceManager> sm(defaultServiceManager());//向ServiceManager注冊SurfaceFling服務(wù) sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);//在SurfaceFlinger調(diào)用init方法的時候,會初始化Display的相關(guān)信息 startDisplayService(); // dependency on SF getting registered above ... return 0;}

系統(tǒng)服務(wù)的注冊過程主要有2點(diǎn)

獲取ServiceManager所對應(yīng)的Binder對象。 通過addService注冊為系統(tǒng)服務(wù)。 ServiceManager的Binder對象獲取

**defaultServiceManager()**方法就是用來獲取ServiceManager服務(wù)的Binder對象。

defaultServiceManager

//frameworksnativelibsbinderIServiceManager.cppsp<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != nullptr) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock);/* * 1. ProcessState::self()->getContextObject(NULL): 返回的是一個 BpBinder. ServiceManager 的 desc 默認(rèn)為0. * 2. interface_cast 就是將 BpBinder 封裝為 IServiceManager,這樣可以直接調(diào)用 IServiceManager 的接口.*//* * 這里,有一個設(shè)計思想. * 1. defaultServiceManager 首先實(shí)例化 BpBinder. * 2. interface_cast 就是 實(shí)例化 BpXXX,并將 BpBinder 交給其管理. * * Proxy 端的用戶無法直接看到 BpBinder , BpBinder 由 BpXXX 持有.用戶本身不關(guān)心 BpBinder 的能力,只關(guān)心 IXXX 定義的 接口. * 所以這里很好的進(jìn)行了封裝.*/ while (gDefaultServiceManager == nullptr) {//如果不為空,表示設(shè)置過了,直接返回 //嘗試不斷的獲取ServiceManager對象,如果獲取不到,就sleep(1), //這里之所以會獲取不到,是因?yàn)镾erviceManager和一些通過init.rc啟動的服務(wù)是同時啟動的,不能保證ServiceManager能夠優(yōu)先啟動完成。 //所以會存在獲取ServiceManager的時候獲取不到。 gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(nullptr)); if (gDefaultServiceManager == nullptr)sleep(1); } } return gDefaultServiceManager;}

這里會直接調(diào)用**ProcessState::self()->getContextObject(nullptr)**來獲取對應(yīng)的服務(wù)。

ProcessState::self()->getContextObject(NULL): 返回的是一個 BpHwBinder。ServiceManager 的 desc 默認(rèn)為0。 interface_cast 就是將 BpBinder 封裝為 IServiceManager

ProcessState::self()

//systemlibhwbinderProcessState.cpp//返回一個ProcessStatesp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != nullptr) { return gProcess; } gProcess = new ProcessState(kDefaultDriver); return gProcess;}

這里會返回一個ProcessState對象。

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)建一個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)不存在的時候,這里會創(chuàng)建一個BpHwBinder對象。所以可以理解為最后我們返回的是一個BpBinder對象

這里,有一個設(shè)計思想:

defaultServiceManager 首先實(shí)例化 BpBinder。 interface_cast 就是 實(shí)例化 BpXXX,并將 BpBinder交給其管理。

Proxy 端的用戶無法直接看到 BpBinder, BpBinder 由 BpXXX 持有.用戶本身不關(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,將一個句柄值為0的Binder代理對象封裝為一個ServiceManger代理對象。將一個句柄值為0的Binder代理對象封裝為一個ServiceManger代理對象。

這里 IServiceManager接口的成員函數(shù)asInterface是通過宏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代理對象 } }return intr; }

到這里為止,我們創(chuàng)建了一個BpIServiceManager對象,并將他的接口IServiceManager返回給了調(diào)用者。

整體的邏輯可以理解為:new BpServiceManager(new BpBinder())。當(dāng)然了,這只是簡化之后的代碼,其內(nèi)部復(fù)雜的邏輯現(xiàn)在可以暫不考慮。整體流程如下:

Android ServiceManager的啟動和工作原理

添加Service

客戶端請求

當(dāng)獲取到ServiceManager服務(wù)之后,就可以使用addService方法來進(jìn)行服務(wù)的注冊了。在獲取服務(wù)的時候,最終返回的是BpServiceManager對象,所以這里我們可以直接找到對應(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對象,這里的remote()方法其實(shí)就是BpBinder對象。

status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ //如果binder已經(jīng)died,則不會返回數(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方法將對應(yīng)的數(shù)據(jù)寫入到了Binder驅(qū)動了。當(dāng)Binder驅(qū)動接收到注冊服務(wù)的信息的時候,就會將對應(yīng)的服務(wù)注冊到ServiceManager中。我們可以看下傳遞的參數(shù):

mHandle:0,表示要處理該請求的進(jìn)程號,ServiceManager在注冊的時候,其對應(yīng)的進(jìn)程號是0。所以處理請求的也就是ServiceManager進(jìn)程。 code:參數(shù)是ADD_SERVICE_TRANSACTION。 data:包含了要添加的進(jìn)程相關(guān)信息:包括名稱、是否單獨(dú)運(yùn)行等等相關(guān)信息

ServiceManager處理請求

當(dāng)客戶端發(fā)送請求之后,我們的ServiceManger就可以接收到消息,并且進(jìn)行消息的處理了。在ServiceManager的啟動中我們了解到,當(dāng)ServiceManger啟動之后,會調(diào)用binder_looper來不斷的循環(huán),檢測是否接收到對應(yīng)的數(shù)據(jù)信息。

這個功能是在binder_loop()方法的入?yún)⒅械膕vcmgr_handler來實(shí)現(xiàn)的。

//frameworksnativelibsbinderndkservice_manager.cppint main(int argc, char** argv){...//啟動循環(huán),等待并處理client端發(fā)來的請求 binder_loop(bs, svcmgr_handler); ...}

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ù)牟煌愋蛠磉M(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ù)的名稱長度不能超過127字節(jié) if (!handle || (len == 0) || (len > 127)) return -1;//最終調(diào)用selinux_check_access方法,會進(jìn)行權(quán)限的檢測,檢查服務(wù)是否有進(jìn)行服務(wù)注冊 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; }//查詢是否已經(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)注冊了,釋放相應(yīng)的服務(wù) svcinfo_death(bs, si); }//更新服務(wù)的handle si->handle = handle; } else {//申請內(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;//將其注冊到服務(wù)列表svclist中,這里使用的鏈表來保存數(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)拿到請求信息之后,ServiceManager會生成對應(yīng)的svcinfo對象,將其保存到服務(wù)列表svclist中。

整體流程如下:

Android ServiceManager的啟動和工作原理

我們也可以從另一個維度去看看Binder的具體

系統(tǒng)服務(wù)獲取

對于Servie服務(wù)的獲取,其實(shí)也是答題思路也是相同的。顯示獲取ServiceManager的Binder對象,然后服務(wù)端發(fā)送獲取某項(xiàng)服務(wù)的請求,ServiceManager來進(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ù)牟煌愋蛠磉M(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來獲取服務(wù)對應(yīng)的handle值 handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid, (const char*) txn_secctx->secctx); if (!handle)break; //返回服務(wù)對應(yīng)的handle bio_put_ref(reply, handle); return 0;}

這里主要做了2個操作:

從服務(wù)列表中獲取到對應(yīng)的服務(wù)的handle 將handle寫入到要返回的reply數(shù)據(jù)中。 do_find_service

//frameworksnativecmdsservicemanagerservice_manager.c //獲取對應(yīng)的服務(wù)uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid, const char* sid){//獲取對應(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; } }//檢測是否有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之后,會調(diào)用**bio_put_ref()**方法將服務(wù)對應(yīng)的handle寫入到返回的數(shù)據(jù)中。

//frameworksnativecmdsservicemanagerservice_manager.cvoid bio_put_ref(struct binder_io *bio, uint32_t handle){ struct flat_binder_object *obj;//申請對應(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;//類型是BINDER_TYPE_HANDLE obj->hdr.type = BINDER_TYPE_HANDLE;//記錄handle obj->handle = handle; obj->cookie = 0;}

對于服務(wù)的獲取,肯定是需要將reply的數(shù)據(jù)寫回到請求服務(wù)的進(jìn)程的。這時候就需要回到我們在binder_loop()函數(shù)了。在該函數(shù)中,存在一個binder_parse(),在這個方法里面會處理請求信息,并將reply信息通過binder驅(qū)動發(fā)送給客戶端。

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ū)動,向Client端發(fā)送reply binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);} ... return r;}

當(dāng)調(diào)用了func函數(shù),有對應(yīng)返回信息之后,會通過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是一個守護(hù)進(jìn)程,負(fù)責(zé)管理系統(tǒng)中的所有服務(wù)信息。通過一個鏈表來保存了所有注冊過的信息。而且其本身也是一個服務(wù),在通過Binder驅(qū)動將其注冊為守護(hù)進(jìn)程之后,會將自己也注冊為一個服務(wù),供其他服務(wù)調(diào)用。

Android ServiceManager的啟動和工作原理

以上就是Android ServiceManager的啟動和工作原理的詳細(xì)內(nèi)容,更多關(guān)于Android ServiceManager的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Android
相關(guān)文章:
主站蜘蛛池模板: 91精品综合久久久久久五月天 | 国产精品乱码一区二区三区 | 久热精品在线 | 久草视频在线播放 | 亚洲成人免费电影 | 国产在线拍揄自揄拍视频 | v亚洲| 国产精品久久久久久久久久久久久 | 成人精品免费视频 | 国产一区网站 | www.一区二区 | 四虎影院在线看 | 久久99视频这里只有精品 | 青青草久久网 | 最近中文字幕免费观看 | 精品毛片在线 | 亚洲精品国产电影 | 精品久久久久久久久久久院品网 | 精品福利在线视频 | 91精品国产一区二区三区蜜臀 | 久久精品久久久久久 | 亚洲最大的黄色网 | 中文字幕在线视频网站 | 日韩欧美二区 | 中文在线播放 | 一区二区三区亚洲精品国 | 国产精品毛片一区二区 | 黄色免费网址大全 | 国产日韩欧美一区二区 | 亚洲1级片 | 龙珠z在线观看 | 视频一区二区三 | 欧美视频在线播放 | 欧美一级h | 国产精品视频一区二区三区 | 国产一区二区三区四 | 精品亚洲国产成av人片传媒 | 久久精品国产亚洲blacked | 不卡av电影在线观看 | 国产伦精品一区二区三区四区视频 | 午夜av电影 | 国产精品美女视频一区二区三区 | 欧美一区二区三区在线视频 | 日本一区视频在线观看 | 欧美性一区二区三区 | 国产精品理论电影 | 国产高清精品一区二区三区 | 一级大片免费观看 | 欧美不卡视频一区发布 | 成人免费小视频 | 91亚洲国产成人久久精品网站 | 中文字幕精品一区 | h视频免费观看 | 国产日韩欧美视频 | 日韩欧美精品一区 | 国产午夜视频 | 国产精品18久久久久久首页狼 | 久久久久久久久久毛片 | 国产成人啪精品午夜在线观看 | 免费小视频 | 日本一区二区三区四区 | 电家庭影院午夜 | 国产又粗又长又硬又猛电影 | 国产精品久久久久久亚洲调教 | 一区二区三区久久 | 久久综合伊人77777 | 日韩欧美综合在线 | 日韩中文在线视频 | 最新国产在线 | 国产网站在线播放 | 日韩在线观看三区 | 女朋友的闺蜜3韩国三级 | 一区免费看| 国产一区二区视频免费看 | 天天操狠狠操 | 羞羞在线视频 | 亚洲日韩欧美一区二区在线 | www日本高清视频 | 国产激情偷乱视频一区二区三区 | 在线免费观看黄 | 日韩一区二区精品视频 | 国产一区精品视频 | 国产精品视频播放 | 成人精品久久久 | 国产亚洲在线 | 精品久久久久久一区二区 | 在线观看免费av网 | 久久av一区二区三区 | 久久精品视 | www.欧美.com | 青青草免费在线视频 | 亚洲在线| 亚洲一区二区三区 | 狠狠干影院 | 日韩在线视频中文字幕 | 亚洲精品资源在线观看 | 国产在线一区二区 | 丁香久久 | 午夜国产精品视频 | 国产在线观看一区二区三区 | 久久精品一区二区国产 | 夜夜操av | 污视频在线免费观看 | 日韩在线视频播放 | 午夜寂寞网站 | 亚洲视频在线观看网址 | 日韩中文字幕免费视频 | 永久精品| 日韩在线中文字幕 | 日韩欧美一区二区三区久久婷婷 | 欧美黄视频在线观看 | 色在线看 | 欧美视频亚洲视频 | 国产一级特黄aaa大片 | 午夜精品一区 | 99免费视频| 华人黄网站大全 | 日韩中文字幕在线 | 伊人网伊人 | 日韩视频中文字幕 | 日本久久精品视频 | 日韩电影专区 | 婷婷激情在线 | 欧美区在线 | 国产乱视频网站 | 日韩视频在线视频 | 久久兔费看a级 | 狠狠操夜夜爱 | 美女福利视频网站 | 久久蜜桃精品一区二区三区综合网 | 国产在线一区二区 | 一区二区在线播放视频 | 伊人久麻豆社区 | 精品免费视频 | 国产日韩欧美激情 | 性处破╳╳╳高清欧美 | 久久久久中文字幕 | 自拍视频在线观看 | 亚洲一区免费观看 | 特大毛片| 91伦理片 | 国产无套丰满白嫩对白 | 人人草在线观看视频 | 日本三级在线网站 | 福利视频网站 | 99精品视频在线 | 在线观看国产一级片 | 国产婷婷在线视频 | 欧美日本在线观看 | 午夜电影网站 | 最新的黄色网址 | 成人国产精品视频 | 日韩成人在线一区 | 在线日韩中文字幕 | 伊人电影综合网 | 国产精品久久国产精麻豆99网站 | 草草网 | 中文字幕亚洲精品 | 成人免费观看男女羞羞视频 | 日韩精品一区二区在线观看 | 色一级 | 欧美一二三四成人免费视频 | 欧美午夜精品久久久久久浪潮 | 欧美日本一区 | 成人av一区二区三区 | 夜夜操导航 | 爱干视频| 国产成人影院在线观看 | 中文字幕精品一区久久久久 | 国产精品久久精品 | 50人群体交乱视频 | 99亚洲 | 一级欧美 | 99精品热视频 | 亚洲欧美综合 | 女同理伦片在线观看禁男之园 | 不卡视频一区二区 | 国产精品久久久久久久久久三级 | 午夜亚洲电影 | 久久久久久久国产 | 久久精品免费观看视频 | 蜜桃av一区二区三区 | 欧美黄色一级 | 网站av | 91精品久久久久久久久入口 | 一区二区三区中文字幕 | 精品91久久久 | 久久久婷| 婷婷色在线 | 欧美激情自拍偷拍 | 欧美高清成人 | av毛片在线免费看 | 99国产视频| 三级无遮挡污在线观看 | 黄色国产区 | 成人黄视频在线观看 | 在线中文字幕日韩 | 五月激情综合 | 超黄视频在线观看 | 欧美日韩在线视频一区二区 | 北条麻妃一区二区三区中文字幕 | 动漫泳衣美女 | 精品一区二区在线观看 | 红杏aⅴ成人免费视频 | 国产精品成人3p一区二区三区 | 国产精品久久久久一区二区三区 | 成人涩涩日本国产一区 | 黄色精品视频 | 日韩欧美久久 | www国产亚洲精品久久网站 | 国产日韩一区 | 91久久综合亚洲鲁鲁五月天 | 狠狠躁天天躁夜夜添人人 | 欧美一区二区三区在线 | 久久国产欧美日韩精品 | 国产精品成人免费视频 | 亚洲成人毛片 | 蜜桃视频成人m3u8 | 黄色片免费在线观看 | 成人午夜性a一级毛片免费看 | 成人天堂资源www在线 | 久草视频在线播放 | 麻豆亚洲| 精品国产乱码简爱久久久久久 | 欧美亚洲国产一区 | 日韩在线视频第一页 | 天堂亚洲 | 剑来在线观看 | 波多野结衣福利电影 | 亚洲欧美国产一区二区 | 亚洲精品资源在线观看 | 日本黄色毛片 | 一区二区三区久久久久久 | 久久97视频 | 一区二区三区国产精品 | 91精品国产一区二区三区四区在线 | 在线免费国产 | 日韩欧美在线视频 | 亚洲视频一区二区三区 | 一级片在线观看 | www.久久精品视频 | 中文字幕亚洲区 | 黄色a级 | 国产精品国产三级国产aⅴ原创 | 亚洲综合精品视频 | 99在线视频观看 | 蜜臀影院 | 91香蕉视频在线观看 | 国产精品99久久久久久宅男 | 中文成人在线 | 成人av一区二区三区 | 精品一区二区三区在线视频 | 鲁一鲁影院 | 91亚洲国产成人精品性色 | 日韩精品日韩激情日韩综合 | 国产免费一区二区三区四区五区 | 日韩免费高清视频 | 一区二区日韩 | 日韩精品一区二区三区中文在线 | 久久久久久久久久久九 | 一区二区三区久久 | 在线视频成人永久免费 | 日本精品久久久一区二区三区 | 嫩草视频在线播放 | 精品网站999www | 在线中文av | 成人日批视频 | 久久精品欧美 | www.成人在线视频 | 亚洲一区 日韩精品 中文字幕 | 精品亚洲一区二区三区 | 国产免费国产 | 在线不卡a资源高清 | 亚洲视频在线看 | 亚洲一区综合 | 亚洲一区二区三区四区在线观看 | 欧美一级在线观看视频 | 视频二区 | 97国产精品视频人人做人人爱 | 国产日韩精品一区二区 | 一区二区三区四区免费看 | 成人在线看片 | 日韩国产一区二区三区 | 91不卡| 一区二区免费在线播放 | 久久久久国产一级毛片 | 自拍偷拍第一页 | 久久久久国产一区二区三区 | 欧美国产一区二区 | av男人的天堂在线 | 日韩91精品 | 久草.com | 一级毛片免费播放 | 精品成人免费一区二区在线播放 | 国产亚洲www | 亚洲一区不卡在线 | 在线免费色视频 | 日韩一区二区黄色片 | 欧美黑人一级毛片 | 日韩免费一区 | 刘亦菲的毛片 | 日韩视频一区二区三区 | 99热这里有精品 | 国产小视频网站 | 一级全黄少妇性色生活片毛片 | 特级毛片在线 | 国产精品久久久久久久电影 | 美国一级毛片a | 午夜色播 | 日韩欧美视频一区 | 成人午夜视频在线观看 | 日韩欧美中字 | 中文字幕日韩一区二区不卡 | 人人爱超碰 | 久久精品成人免费视频 | 欧美精三区欧美精三区 | 国产1页| 日韩欧美在线视频播放 | 狠狠色丁香婷婷综合 | 黄色一级免费观看 | 99久久久久久 | 国内精品一区二区 | 日韩成人在线观看 | 最新日韩在线观看视频 | 欧美日韩在线观看视频 | 综合久久一区 | 国产一区在线免费观看 | 久久亚洲视频 | 午夜寂寞少妇aaa片毛片 | 91精品久久久久久久久久小网站 | 成人免费视频观看视频 | 在线成人av | 五月激情综合网 | 国产成人午夜视频 | 欧美一区二区三区免费在线观看 | 一区二区三区在线免费观看 | 精品久久久av | 国产精品一二三区 | 中文字幕高清在线 | 99久久精品一区二区成人 | 91精品国产综合久久精品 | 中文字幕一区在线观看 | 亚洲一区视频网站 | 一级黄色大片在线 | 91福利在线导航 | 色五月激情五月 | 久久在线视频 | 成人免费一区二区三区视频网站 | 久久久久99精品国产片 | 成人在线播放网站 | 久久精品1区 | 亚洲一区二区三区在线播放 | 在线日韩成人 | 久久久精品一区二区三区 | 色综合久久88色综合天天 | 第一福利丝瓜av导航 | 日本亚洲最大的色成网站www | 久久久久久亚洲精品 | 国产在线一区二区三区 | 国产精品女教师av久久 | 欧美日韩国产在线观看 | 久在线视频 | 久草av在线播放 | 91xxx在线观看| 国产色 | 中出片 | 一级毛片免费播放 | 日韩在线不卡 | 欧美视频在线播放 | 五月激情综合网 | 中文字幕在线免费看 | 欧美精品第一页 | 免费av一区二区三区 | 久久久久久av | 日韩高清中文字幕 | 在线视频91 | 亚洲精品视频免费看 | 中文字幕日韩视频 | 日韩欧美高清dvd碟片 | 粉嫩国产精品一区二区在线观看 | 日本全黄裸体片 | 偷拍自拍第一页 | 国产专区一区 | 一本大道综合伊人精品热热 | 欧美一级久久久 | 午夜无码国产理论在线 | 日韩在线欧美 | 久久人人爽爽爽人久久久 | 成人一区二区在线 | 国产三级在线播放 | 久久久久久久久久久久久久久久久久久 | 国产亚洲女人久久久久毛片 | 青青草视频网站 | 欧美精品乱码久久久久久按摩 | 欧美三及片 | 日韩中文久久 | 国产人妖一区二区 | 亚洲综合色自拍一区 | 精品无人乱码一区二区三区 | 亚洲在线视频 | 午夜影院18 | 亚洲精品二区三区 | 亚洲色图偷拍视频 | www.成人在线视频 | jizz欧美最大 | 欧美综合国产精品久久丁香 | 91偷拍精品一区二区三区 | 免费黄色特级片 | 国产区第一页 | 久久久tv | 99re在线视频 | 久久密 | 一区日韩 | 国产综合久久久久久鬼色 | 91精品国产乱码久久久久久久久 | 刺激网 | 国产成人亚洲综合 | 91av免费在线观看 | 日本精品久久 | 日日干夜夜干 | 爱色区综合网 | 伊人久麻豆社区 | 国产在线观看一区 | 欧美一级片在线观看 | 91免费看片 | 欧美亚洲91| 亚洲精品一区二区三区在线 | 91大神在线看 | 一区二区久久久 | 国产精品久久久久久久午夜 | 天天澡天天狠天天天做 | 国产在线不卡 | 日本aa级毛片免费观看 | 四虎成人在线播放 | 一本色道精品久久一区二区三区 | 日本激情在线 | 美女又黄又免费 | 婷婷免费视频 | 国际精品久久 | 国产精品久久久久一区二区三区 | 亚洲精品国产第一综合99久久 | 香蕉视频一级片 | 91精品国产综合久久久久久丝袜 | 狠狠爱www人成狠狠爱综合网 | 日本免费不卡 | 国产精品久久久久久久午夜片 | 天堂中文在线视频 | 亚洲视频一区二区三区四区 | 久久av一区二区 | 日韩精品| 成人免费在线视频 | 日韩精品一区在线视频 | 日韩激情网 | 在线观看国精产品二区1819 | 亚洲激情在线 | 日本成人在线视频网站 | 久久精品二区 | 亚洲男人天堂2023 | 日韩免费视频一区二区 | 一区二区三区影视 | www.蜜桃av| 亚洲男人的天堂在线播放 | 亚洲成人免费观看 | 在线观看亚洲视频 | 99亚洲 | 99热这里有| 亚洲成人久久久 | 欧美精品综合 | 午夜影院免费体验区 | 国产一级黄 | 国产高清视频一区二区 | 99精品一区二区三区 | 久久亚洲一区二区三区四区五区高 | 久久久免费视频播放 | 国产成人久久精品一区二区三区 | 欧美日韩在线观看视频 | 亚洲热在线观看 | 日韩一区二区在线观看 | 亚洲一区二区三区四区五区中文 | 精品亚洲一区二区三区四区五区 | 国产精品一区二区三区在线 | 在线一区观看 | 日韩精品中文字幕在线观看 | 欧美精产国品一二三区 | 国产成人精品免费视频大全最热 | 亚洲精品国产偷自在线观看 | 久久久免费视频看看 | 国产成人在线免费观看视频 | 9191视频 | 日韩综合一区 | 国产成人免费视频 | 蜜桃官网| 欧美精产国品一二三区 | 亚州综合一区 | 国产成人精品一区二 | 国产精品日韩三级 | 国产在线不卡 | 欧美日韩一区二区在线观看 | 欧美国产视频 | 亚洲午夜精品一区二区三区 | 天堂久久一区 | 亚洲精品福利 | 国产精品18hdxxxⅹ在线 | 亚洲一区 中文字幕 | 久久久精品综合 | 中文字幕亚洲欧美日韩在线不卡 | 青青草一区二区 | 国产中文视频 | 91在线播| 99热这里有精品 | 成人免费福利视频 | 午夜色电影 | 久久国产欧美日韩精品 | 亚洲男人av| 免费av毛片 | 午夜在线视频 | 91精品欧美久久久久久久 | 91久久精品一区二区二区 | 一区在线视频 | 久久成人久久爱 | 伊人午夜| 国产综合精品一区二区三区 | 国产精品777一区二区 | 日韩精品一区二区三区在线观看 | 国产一区二区在线免费 | 国产特级毛片 | 91麻豆视频 | 91国视频 | 久久综合久 | 午夜精品一区二区三区在线播放 | 久久久久久久国产精品 | 免费亚洲网站 | 国产精品久久免费视频 | 日韩一区二区在线观看视频 | 久久久久久久av | 精品在线一区 | 午夜少妇av| 香蕉成人啪国产精品视频综合网 | 九九久久久 | 欧美成人精品一区二区男人看 | 超碰8| 亚洲a网站 | 久久精品网 | 国产欧美专区 | 欧美日韩亚洲视频 | 在线99视频 | 在线亚洲精品 | 国产午夜精品一区二区三区视频 | concern超碰在线| 国产精品久久久一区二区 | 亚洲精品片| 亚洲蜜臀av乱码久久精品蜜桃 | 国产一区二区三区av在线 | 亚洲欧洲日韩在线 | 91久久久久久久久久久久久久久久 | v888av成人 | 成人在线 | 日韩性猛交 | 欧美精品亚洲精品 | 国产综合久久 | 欧洲亚洲视频 | 免费看一区二区三区 | 欧美成人在线免费观看 | 久久久久久久国产精品 | 最新日韩视频 | 欧美一区久久 | 欧美日韩视频一区二区 | 国产精品久久嫩一区二区 免费 | 久久草草影视免费网 | 全黄大全大色全免费大片 | jizz久久久| 涩涩视频在线免费看 | 免费成人av | 免费午夜电影 | 一区二区三区免费 | 亚洲 中文 欧美 日韩在线观看 | 91天天综合| 亚洲欧洲一区二区 | 毛片综合 | 久久久久久久久久久成人 | 欧美日韩电影一区二区 | 日韩精品1区2区3区 国产精品国产成人国产三级 | 日韩在线视频一区 | av久久| 超碰在线影院 | 免费在线一区二区 | 久久久久久黄 | 男女羞羞视频网站18 | 久久精品色欧美aⅴ一区二区 | 亚洲高清免费视频 | 激情婷婷| 特黄视频 | 亚洲午夜视频在线观看 | 99综合| www国产亚洲精品久久网站 | 国产精品久久久久久久久 | 日日摸日日爽 | 久久久久久亚洲精品 | 亚洲综合99| 亚洲精选免费视频 | www.久草.com | 久久va | 久久三级视频 | 日韩精品2区 | 一区二区三区精品视频 | 欧美激情在线狂野欧美精品 | 成人在线国产 | 成人网在线观看 | 久久久国产精品免费 | 日韩视频精品 | 国产精品久久久久国产精品 | 日韩精品一区二区三区在线 | 91视频免费看片 | 伊人久操 | 亚洲精品www |