1) binder机制
binder驱动
Service Manager负责管理Android系统中所有的服务。每个服务需要向Service Manager注册自己提供的服务,以便客户端进行查询和获取;客户端与服务端通信前,需要通过Service Manager查询和取得所需要交互发服务。
服务器端 通常是Android的系统服务
客户端 Android系统上的应用程序,如Activity
代理服务器 客户端应用程序中生成的Server代理(proxy)
BinderAdapter对Binder驱动进行封装,主要用于操作Binder驱动,使应用程序不必直接接触Binder驱动程序。实现包括IPCThreadState.cpp和ProcessState.cpp.
Binder核心库是Binder框架的核心实现,主要包括IBinder,Binder(服务器端)和BpBinder(客户端 服务器代理)。
服务流程:
(1)客户端首先获得服务器端的代理对象。即在客户端建立一个服务器的“引用”,使客户端访问服务器的方法就像访问本地方法一样。
(2)客户端通过调用服务器代理对象的方式向服务器发送请求。
(3)代理对象将用户请求通过Binder驱动发送到服务器进程。
(4)服务器进程处理用户请求,并通过Binder驱动返回结果给客户端的服务器对象
(5)客户端收到服务器端的返回结果。
2) Binder Adapter
ProcessState.cppmyandroid2.3frameworksbaselibsbinder;
IPCThreadState.cppmyandroid2.3frameworksbaselibsbinder;
ProcessState.hmyandroid2.3frameworksbaseincludebinder
IPCThreadState.hmyandroid2.3frameworksbaseincludebinder;
ProcessState类包含通信细节,利用open打开binder设备,利用ioctl建立基本的通信框架。它是一个Singleton类新,用于维护当前进程中所有的Service代理,一个客户端进程可能会创建多个Service代理。
每个进程只有一个ProcessState对象,而每个线程都会有一个IPCThreadState对象负责Binder数据存取、写入和请求处理框架。
当一个服务启动,会调用ProcessState::self()函数获得一个ProcessState实例:
ProcessState::ProcessState()
:mDriverFD(open_driver()) //打开binder设备
,mVMStart(MAP_FAILED)//映射内存的起始地址
,mManagesContexts(false)
,mBinderContextCheckFunc(NULL)
,mBinderContextUserData(NULL)
,mThreadPoolStarted(false)
,mThreadPoolSeq(1)
{
if(mDriverFD >= 0) {
// XXX Ideally, there should be a specific definefor whether we
// have mmap (or whether we could possibly have the kernelmodule
// availabla).
#if !defined(HAVE_WIN32_IPC)
// mmap the binder, providing a chunk of virtualaddress space to receive transactions.
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE |MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
LOGE("Using /dev/binder failed: unable to mmap transactionmemory.n");
close(mDriverFD);
mDriverFD = -1;
}
#else
mDriverFD = -1;
#endif
}
if(mDriverFD < 0) {
// Need to run without the driver, starting our own threadpool.
}
}
ProcessState还维护一个线程池,可通过ProcessState::startThreadPool()开启线程池,该线程池维护所有的服务器代理,当需要创建一个服务器代理对象时,就会调用getStrongProxyForHandle来实现。
sp<IBinder>ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex_l(mLock);
handle_entry* e = lookupHandleLocked(handle);//查询当前所有服务器代理
if (e !=NULL){//若不在已存在的服务器代理列表中
// We need to create a new BpBinder if thereisn't currently one, OR we
// are unable to acquire a weak reference on this currentone. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL ||!e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs =b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us toadd a primary
// reference to the remote proxy when this team doesn't haveone
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
returnresult;
}
所有关于Binder的操作都放置在IPCThreadState中,重要函数有:
talkWithDriver() 读取/写入通过ioctl对ProcessState打开的句柄进行读写
executeCommand() 请求处理
joinThreadPool() 循环结构
不管客户端进程还是Service进程都需要用IPCThreadState来与Binder设备通信。若为客户端进程,通过BpBinder调用transcat函数,把客户端请求写入Binder设备另一端的Service进程;若为Service进程,当初始化完成后,调用它的IPCThreadState对象的joinThreadPool方法开始轮询Binder设备,等待客户端请求的到来。
3) ServiceManager
Service_manager.cmyandroid2.3frameworksbasecmdsservicemanager
service servicemanager/system/bin/servicemanager
//myandroid2.3/system/core/rootdir/init.rc
usersystem
critical
onrestartrestart zygote
onrestart restart media
android启动后自动运行核心进程servicemanager
int main(int argc, char**argv)//service_manager.c中
{
structbinder_state *bs;
void*svcmgr = BINDER_SERVICE_MANAGER;
bs =binder_open(128*1024);
if(binder_become_context_manager(bs)) {//通过ioctl把自身设置为service Manager
LOGE("cannot become context manager (%s)n", strerror(errno));
return -1;
}
svcmgr_handle = svcmgr;
binder_loop(bs, svcmgr_handler);//循环等待请求,回调函数svcmgr_handler
return0;
}
int svcmgr_handler(struct binder_state *bs,
struct binder_txn *txn,
struct binder_io *msg,
struct binder_io *reply)
{
structsvcinfo *si;
uint16_t*s;
unsignedlen;
void*ptr;
uint32_tstrict_policy;
//LOGI("target=%p code=%d pid=%d uid=%dn",
//txn->target, txn->code,txn->sender_pid,txn->sender_euid);
if(txn->target != svcmgr_handle)
return -1;
//Equivalent to Parcel::enforceInterface(), reading the RPC
// headerwith the strict mode policy mask and the interface name.
// Notethat we ignore the strict_policy and don't propagate it
//further (since we do no outbound RPCs anyway).
strict_policy = bio_get_uint32(msg);
s =bio_get_string16(msg, &len);
if ((len!= (sizeof(svcmgr_id) / 2)) ||
memcmp(svcmgr_id,s, sizeof(svcmgr_id))) {
fprintf(stderr,"invalid id %sn", str8(s));
return -1;
}
switch(txn->code) {//获取服务或查询服务
caseSVC_MGR_GET_SERVICE:
caseSVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
ptr= do_find_service(bs, s, len);
if (!ptr)
break;
bio_put_ref(reply, ptr);
return 0;
caseSVC_MGR_ADD_SERVICE: //添加服务
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
if (do_add_service(bs, s, len, ptr,txn->sender_euid))
return -1;
break;
caseSVC_MGR_LIST_SERVICES: {
unsigned n = bio_get_uint32(msg);
si = svclist;
while ((n-- > 0) &&si)
si = si->next;
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
LOGE("unknown code %dn", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return0;
}
当有新的服务需要添加时,或者客户端要获得已经添加的服务时都会触发回调函数。SVC_MGR_ADD_SERVICE是通过do_add_service函数实现的。代码如下:
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
void *ptr, unsigned uid)
{
structsvcinfo *si;
//LOGI("add_service('%s',%p) uid=%dn", str8(s), ptr, uid);
if (!ptr|| (len == 0) || (len > 127))
return -1;
if(!svc_can_register(uid, s)) {
LOGE("add_service('%s',%p) uid=%d - PERMISSION DENIEDn",
str8(s), ptr, uid);
return -1;
}
si =find_svc(s, len);
if (si){
if (si->ptr) {
LOGE("add_service('%s',%p) uid=%d - ALREADY REGISTEREDn",
str8(s), ptr, uid);
return -1;
}
si->ptr = ptr;
} else{
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
if (!si) {
LOGE("add_service('%s',%p) uid=%d - OUT OF MEMORYn",
str8(s), ptr, uid);
return -1;
}
si->ptr = ptr;
si->len = len;
memcpy(si->name, s, (len + 1) *sizeof(uint16_t));
si->name[len] = ' ';
si->death.func = svcinfo_death;
si->death.ptr = si;
si->next = svclist;
svclist = si;
}
binder_acquire(bs, ptr);
binder_link_to_death(bs, ptr,&si->death);
return0;
}
添加过程为:
首先检查是否有权限注册service;
然后检查是否已经注册过service,若注册过相同的service,则不能再次注册;
接下来构造一个svcinfo对象,并将其加入到一个全局链表svclist中;
最后通知binder设备有一个service注册进来,添加Binder后会为每一个服务维护一个句柄。
当客户端需要获得一个服务时,触发SVC_MGR_GET_SERVICE,再调用do_find_service来查询指定服务,找到后写入reply中返回给客户端。
3) Binder机制(IBinder接口)
C/S 客户端 服务器代理 驱动 服务器
IBinder.hmyandroid2.3frameworksbaseincludebinder
Android对binder机制进行抽象即IBinder接口,它在JAVA/C++层定义了使用binder机制实现客户程序和服务程序的通信协议。
IBinder对象既可以指向本地对象,也可以指向远端对象。关键在于IBinder接口中的transact函数,如果IBinder指向是一个服务器代理,则transact只负责把请求发送给服务器;如果IBinder指向一个服务器,则transact负责提供服务即可。都必须实现该接口。
服务器代理对象BpBinder
它是Binder通信存在于客户端的进程,它实现了IBinder接口,它的transact函数的实现代码如下:
status_t BpBinder::transact(
uint32_tcode, const Parcel& data, Parcel* reply, uint32_tflags)
{
// Once abinder 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;
}
returnDEAD_OBJECT;
}
服务端BBinder
同样需要实现IBinder接口,以Android默认的服务端实现类BBinder为例。
如果是PING_TRANSACTION请求,则仅将pingBinder的值返回给调用者;如果为其他的,则调用onTransact函数处理。onTransact是Bbinder中申明的一个protected类新的虚函数,需要子类实现。