Android Binder Native
来源:互联网 发布:米拉奇战记无敌版软件 编辑:程序博客网 时间:2024/05/22 16:00
我们要知道,Android系统基本上可以看做是一个基于Binder通信的C/S架构,Binder把Android系统的各个部分都连在了一起,所以它的重要不可言喻,我们有必要掌握好它。
Binder是Android系统提供的一种 “ 进程间通信(IPC)” 机制。在基于Binder的C/S**(Client、Service)架构中除了 **Client和Service端外、Android还有一个ServiceManager,它管理系统中的各种服务。
由上图可知:
- Server进程要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端.
- 如果某个Client进程要使用Server,则必须先去ServiceManager去查询服务,所以Client是ServiceManager的客户端
- Client根据得到的Service信息与Service所载的Server进程建立通信线路,然后就可以和Service交互了,所以Client是Service的客户端
我们要分析Binder,必然要以一个入口来分析它,由于我没有自行分析过C层代码,所以就按照我所学的来,用MediaServer来打开我们的Binder之路。
以下代码使用在线阅读网站:http://androidxref.com/进行阅读,且代码版本为 7.1.1_r6
MediaServer(main_mediaserver.cpp)
源码位置:
1. 4.0.x版本路径
2. 4.0.x以上版本
Notice:以下代码省略了大部分与分析无关的代码。
分析:
进入main_dediaserver.cpp中我们可以看见,内部只有一个main方法
int main(int argc __unused, char **argv __unused){ sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm(defaultServiceManager()); MediaPlayerService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }
上面操作总共分为5部分。
1. 获得一个ProcessState实例
2. 获取一个IServiceManager
3. 多媒体系统MediaPlayer服务
4. 创建线程池
5. 将自己加入线程池中
由上面5部分我们进行代码分析..
ProcessState::self
ProcessState::self()
进入ProcessState的self方法 ProcessState.cpp
sp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess;}
看上面代码得知,如果gProcess不等于null,那么直接返回。 否则新建一个ProcessState 并赋值给gProcess 然后返回。由代码可知,self采用了单例模式,说明了每个进程中只能有一个ProcessState。 下面进入ProcessState构造
ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) ....... ......{ if (mDriverFD >= 0) { mVMStart=mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { close(mDriverFD); mDriverFD = -1; } }}
在上面代码中,我们看open_driver()
open_driver():该函数的作用是 用来打开/dev/binder 这个设备,它是Android在内核中用来完成进程间通信的一个虚拟设备.
mmap():BINDER_VM_SIZE =(1*1024*1024) -(4096*2) =1M-8k,该函数实现后,binder驱动会分配一块内存区域来接收数据
static int open_driver(){int fd = open("/dev/binder", O_RDWR | O_CLOEXEC); if (fd >= 0) { .... size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); .... } return fd;}
上面代码做了2件事
1. 打开binder设备
2. 通过ioctl的方式告诉binder驱动,该fd最大支持线程数
所以由ProcessState::self可知:
- ProcessState进程唯一
- 打开了/dev/binder 虚拟设备
- 打开后使用mmap,Binder驱动会分配一块内存接收数据
defaultServiceManager
defaultServiceManager返回的是一个IServiceManager对象,通过它我们可以与别的进程的ServiceManager进行交互。
下面分析代码 IServiceManager.cpp
sp<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { ... while (gDefaultServiceManager == NULL) { gDefaultServiceManager=interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); if (gDefaultServiceManager == NULL) sleep(1); } } return gDefaultServiceManager;}
看代码可知,是个单例,接着调用了3个方法来获取gDefaultServiceManager.
1. 先获取ProcessState实例
2. 调用ProcessState的getContextObject函数,注意参数为NULL
3. 把getContextObject返回的变量作为interface_case参数调用
首先来看getContextObject ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(constsp<IBinder>& caller){ return getStrongProxyForHandle(0);}
可以看到这里直接调用了getStrongProxyForHandle(0).. 注意传入的是个0..并返回了IBinder…
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){ sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) { ..... b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } return result;}
- lockupHandleLocked:该函数参数handle代表的意义为索引,根据索引去一个资源数组里面去寻找资源,如果没有则创建一个新的项并返回。
- 对于新创建的资源, binder为null,所以进入分支,然后创建BpBinder,并赋值handle_entry 的binder, 最后赋值给result.
- 返回BpBinder(handle), handle的值为0.
BpBinder是什么?
IPC内重要部分其中就是BpBinder,实现了IBinder类。
IBinder 有两个实现类,分别是 BpBinder、BBinder。
- BpBinder是客户端用来与服务端交互的代理类,p 译为proxy
BBinder则是服务端.
BpBinder 与BBinder是一一对应的。
BpBinder.cpp
BpBinder::BpBinder(int32_t handle): mHandle(handle), mAlive(1), mObitsSent(0), mObituaries(NULL){extendObjectLifetime(OBJECT_LIFETIME_WEAK);IPCThreadState::self()->incWeakHandle(handle);}
由上面代码我们看到了一个IPCThreadState,它是什么?
现在我们知道了getContextObject() 实际染回的是一个BpBinder(0)对象,那么代码就变成了interface_cast(new BpBinder(0));
interface_cast是什么? 我们可以在IInterface.h内查看它的定义.
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}
可以看到这相当于一个模版,根据传进来的泛型来调用泛型类所对应的方法,那么我们可以接着看IServiceManager::asInterface(new BpBinder(0)).
我们想象一下,BpBinder和BBinder是用于通信的,那么如何和这些东西关联上?答案就是通过IServiceManager,下面看IServiceManager的定义
IServiceManager.h
class IServiceManager : public IInterface{public:DECLARE_META_INTERFACE(ServiceManager);....virtual sp<IBinder> getService( const String16& name) const = 0;virtual sp<IBinder> checkService( const String16& name) const = 0;virtual status_t addService( const String16& name,const sp<IBinder>& service, bool allowIsolated = false) = 0;virtual Vector<String16> listServices() = 0;.....};
需要注意的是 DECLARE_META_INTERFACE(ServiceManager),其余则是提供给ServiceManager的一些方法.
前面说到过,如何与BpBinder和BBinder关联上? 实际则是通过DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE 这两个宏来关联的。它们两个的定义在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();
DECLARE_META_INTERFACE(ServiceManager) 把ServiceManager替换得到下面这样。
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();
由名字可知,DECLARE 为定义,那么IMPLEMENT肯定为实现了。原始宏就不贴代码了,跟上面一个套路。我们来看看它的实际使用。
IServiceManager.cpp
IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");
它在IServiceManager.cpp 中的最后一行代码,经过Interface.h宏定义的模版转换后,那么就变成下面的样子
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 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() { }
现在我们知道了,interface_cast 《IServiceManager》(new BpBinder(0)),最后是调用了 IServiceManager::asInterface(new BpBinder(0)),最后把BpBinder(0)作为参数 来创建BpServiceManager。
BpServiceManager是什么?要明白这个问题,我们先来了解一下IServiceManager相关类的关系。
在BpServiceManager的构造内 会调用BpInterface构造,并把参数传递,最后会赋值给BpRefBase的 mRemote, 到这,就和BpBinder联系上了。
到这里 defaultServiceManager分析完成,它主要完成了以下工作。
- 创建了一个BpBinder对象,handle值为0
- 创建了一个BpServiceManager 并把 BpBinder赋值给mRemote
知道了通信层是如何工作的,那么业务层是怎样的?我们通过MediaPlayerService来分析一下。
MediaPlayerService::instantiate();
void MediaPlayerService::instantiate() { defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());}
defaultServiceManager 返回BpManagerService.
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; }
把Parcel数据包打包 并传给BpBinder的transact函数.
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ if (mAlive) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT;}
可以看到,实际上BpBinder只是个工具!!! 实际操作的是IPCThreadState。
下面分析IPCThreadState.cpp
IPCThreadState* IPCThreadState::self(){ if (gHaveTLS) {restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if (st) return st; return new IPCThreadState; } goto restart;}
gTLS: TLS为(Thread Local Storage)简称,为线程本地存储空间,每个线程都有一个,pthread_getspecific 从TLS内获取IPCThreadState,如果有就返回,没有就创建一个。
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), mMyThreadId(gettid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0){ pthread_setspecific(gTLS, this); clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256);}
IPCThreadState构造内调用pthread_setspecific 把自己设置进去,并设置mIn,mOut缓冲区(两个Parcel) 用来接收和发送数据。
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 (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } ..... return err;}
BC_TRANSACTION 是应用程序向Binder设备发送消息的消息码,binder设备回复信息以BR_开头。
5status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer){ binder_transaction_data tr; tr.target.ptr = 0; //handle为0,表示目的端ServiceManager tr.target.handle = handle; tr.code = code; tr.flags = binderFlags; tr.cookie = 0; tr.sender_pid = 0; tr.sender_euid = 0; ..... ..... mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); return NO_ERROR;}
最后把命令写到mOut中,接下来走writeForResponse
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){ uint32_t cmd; int32_t err; while (1) { //注意talkWithDriver if ((err=talkWithDriver()) < NO_ERROR) break; err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; cmd = (uint32_t)mIn.readInt32(); switch(cmd){ ..... default: err = executeCommand(cmd); break; } .... return err;
假设我们发送后,马上得到了回复,然后我们看executeCommand(cmd),其内根据一些binder设备 返回的 以BR开头的码来做不同的事情。
status_t IPCThreadState::executeCommand(int32_t cmd){ BBinder* obj; RefBase::weakref_type* refs; status_t result = NO_ERROR; switch ((uint32_t)cmd) { case BR_ERROR: result = mIn.readInt32(); break; .... case BR_TRANSACTION: { .... .... if (tr.target.ptr) { .... error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags); reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this); .... } } else { error = the_context_object->transact(tr.code, buffer, &reply, tr.flags); } } break;
上面把tr.cookie转成了BBinder,它的实际对象是BnServiceManager,我们来看BBinder的transaction.
status_t BBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ data.setDataPosition(0); status_t err = NO_ERROR; switch (code) { case PING_TRANSACTION: reply->writeInt32(pingBinder()); break; default: err = onTransact(code, data, reply, flags); break; } if (reply != NULL) { reply->setDataPosition(0); } return err;}
这里的onTransact函数会调用到BBinder子类的onTransact,然后子类进行处理。可以在这里 查看onTransact函数,知道这一处,别的都一样。
发送请求是在talkWithDriver内,这里就不贴代码了。其内主要是用ioctl方式来发送请求。到这为止,发送与接收就告一段落了继续分析下面。
startThreadPool
void ProcessState::startThreadPool(){ AutoMutex _l(mLock); //如果已经 startThreadPool过,则略过 if (!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true);// 这里为true }}
void ProcessState::spawnPooledThread(bool isMain){ if (mThreadPoolStarted) { String8 name = makeBinderThreadName(); sp<Thread> t = new PoolThread(isMain); t->run(name.string()); }}
PoolThread是ProcessState内 Thread的一个子类
class PoolThread : public Thread{public: PoolThread(bool isMain) : mIsMain(isMain) { }protected: virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); return false; } const bool mIsMain;};
接着调用了IPCThreadState的joinThreadPool方法.
void IPCThreadState::joinThreadPool(bool isMain){ //如果为true 则循环处理,把信息写到mOut内 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); set_sched_policy(mMyThreadId, SP_FOREGROUND); status_t result; do { //处理已经死亡的BBinder processPendingDerefs(); result = getAndExecuteCommand(); if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) { ..... mProcess->mDriverFD, result); abort(); } if(result == TIMED_OUT && !isMain) { break; } } while (result != -ECONNREFUSED && result != -EBADF); (void*)pthread_self(), getpid(), (void*)result); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false);}
在getAndExecuteCommand内 又调用了talkWithDriver 发送请求给binder,和executeCommand 接收回复的方法。
所以由以上代码可知,主线程,和startThreadPool的线程 分别在读取binder设备,查看是否有请求。
到这里,我们应该大体明白了Binder的流程。
1. 创建BpBinder(0)
2. 创建BpServiceManager(BpBinder(0)),在BpServiceManager内,把BpBinder赋值给了mRemote,至此业务层关联了BpBinder
3. 注册服务,调用BpServiceManager的addService函数,在其内调用 BpBinder的transact.
4. 创建IPCThreadState并调用 它的transact,传入的参数mHandler为0,用户标示目的地的服务端(ServiceManager).
5. 在transact内的waitForResponse内 while(1){来发送,等待接收binder消息}
6. 在while(1){}内 的executeCommand内的 case BR_TRANSACTION:内 获取了BBinder 然后调用其 transact.
7. BBinder 的transact调用了子类的 onTransact函数.
至此消息发送到了服务端的onTransact函数,完成了进程间通信(IPC)
疑问 , 谁是BBinder的子类 用来接收onTransact函数。?
答案是ServiceManager来做这些工作的。
可以说,如果想要进程间通信,则必须向ServiceManager注册服务,然后客户端通过向ServiceManager查询 获取到的Server 来进行响应处理。
有关于ServiceManager从onTransact接收后 如何处理,请大家自定去分析~~~链接上面已给。
- Android Native Binder
- Android Binder Native
- Android创建Native Binder Service
- Android Binder机制的Native应用
- android Binder机制3---Native层
- android libbinder – Binder的Native实现
- 如何创建一个Android Native Binder Service
- Android Binder机制的Native应用
- android binder机制---native获取ServiceManager
- Android中实现native服务利用binder与应用通信
- Android Framework 深入浅出-HAL, Binder, View System 与 Native Service
- Android Binder机制的Native应用—双向通信
- Android Binder机制的Native应用—双向通信
- Android系统的Binder机制及其native层应用
- Android Binder机制的Native应用—双向通信
- Android下在C++环境实现native层binder服务
- Android Framework:Binder(4)-Native Service的注册
- android binder机制,注册系统服务---native客户端
- mongo基本操作
- Linux
- Java
- Java
- Linux
- Android Binder Native
- Find The Multiple
- Linux下信号--阻塞信号
- 神经网络不胜语, M-P模型似可寻(深度学习入门系列之三)
- C语言指针导学(5)——指针与结构
- 关于binary log那些事
- 随笔2017-06-06
- POJ 1863 Subnumber 笔记
- 说说MySQL中的Redo log Undo log都在干啥