已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Binder基本概念流程学习一 Media Service进程启动Init.rc中描述的service对应linux 的进程:Media进程定义:service media /system/bin/mediaserver class main user media group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc ioprio rt 4servicemanager 进程定义:service servicemanager /system/bin/servicemanager class core user systemgroup systemMedia中有很多Native Service(AudioFlinger MediaPlayerService CameraServiceAudioPolicyService等),整个Android(native或者framework)的Service都需要加入servicemanager中进行统一管理。那么Media Process 与ServiceManager Process是如何进行通信的呢Binder.通过Media Process中使用binder进行完成IPC过程,学习Binder的概念和使用方法。frameworksavmediamediaserver main_mediaserver.cpp:int main(int argc, char* argv) /创建ProcessState 当前进程属性 sp proc(ProcessState:self(); /IServiceManager对象 sp sm = defaultServiceManager(); /初始化MediaPlayerService服务对象 MediaPlayerService:instantiate(); /启动进程的线程池 ProcessState:self()-startThreadPool(); /执行线程消息循环 IPCThreadState:self()-joinThreadPool();Sp:指针运算符和普通运算符的重载 StrongPointer。二 Media Process执行过程1 ProcessState对象创建当前进程的状态属性,对象创建:sp ProcessState:self() Mutex:Autolock _l(gProcessMutex); if (gProcess != NULL) return gProcess; gProcess = new ProcessState; return gProcess;ProcessState构造函数:ProcessState:ProcessState() : mDriverFD(open_driver() /打开binder驱动设备 , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) if (mDriverFD = 0) /将binder的fd映射到当前进程虚拟空间地址中 与binder进行交互 mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); 打开binder设备:static int open_driver() /打开binder设备驱动 int fd = open(/dev/binder, O_RDWR); if (fd = 0) /bidner最大支持线程数 size_t maxThreads = 15; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); return fd;ProcessState对象创建过程所做的事:打开/dev/binder设备,得到binder设备的fd;将bidner设备fd映射到当前进程虚拟地址空间建立交互的通道;2 IServiceManager对象创建sp sm = defaultServiceManager();为什么需要一个IServiceManager对象呢,这个类是个抽象提供接口class IServiceManager : public IInterface virtual sp getService( const String16& name) const = 0; virtual status_t addService( const String16& name, const sp& service, bool allowIsolated = false) = 0; ;通过IServiceManager派生对象操作将Service加入到ServiceManager中.defaultServiceManager()函数:sp defaultServiceManager() /单例对象 if (gDefaultServiceManager != NULL) return gDefaultServiceManager; AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager = NULL) /创建对象 gDefaultServiceManager = interface_cast( ProcessState:self()-getContextObject(NULL); return gDefaultServiceManager;ProcessState:self()-getContextObject(NULL):得到一个IBinder对象ProcessState:self()刚才所创建的ProcessState对象。sp ProcessState:getContextObject(const sp& caller) return getStrongProxyForHandle(0);sp ProcessState:getStrongProxyForHandle(int32_t handle) sp result; AutoMutex _l(mLock); /从表中查询一个handle对应的handle_entry /若没有则创建一个 handle = 0 handle_entry* e = lookupHandleLocked(handle); if (e != NULL) IBinder* b = e-binder; if (b = NULL | !e-refs-attemptIncWeak(this) /handle_entry对象成员初始化 创建handle=0的BpBinder b = new BpBinder(handle); e-binder = b; if (b) e-refs = b-getWeakRefs(); result = b; return result;handle_entry是什么呢?struct handle_entry IBinder* binder; RefBase:weakref_type* refs; ;也就是说ProcessState 有一个表VectormHandleToObject;表里面的每一项存储了一个binder,每一个binder对应一个handle。Handle = 0是什么,句柄? 代表谁的句柄ServiceManager在binder中的资源。从ProcessState:self()-getContextObject(NULL)得到一个 IBinderBpBinder(0);于是得到:gDefaultServiceManager = interface_cast(BpBinder(0);使用interface_cast将IBinder实例转化成IServiceManager实例。3 interface_cast函数frameworksnativeincludebinderIInterface.h:interface_cast是个内联模板函数:templateinline sp interface_cast(const sp& obj) return INTERFACE:asInterface(obj);结合前面就是:inline sp interface_cast(const sp& obj) return IServiceManager:asInterface(obj);所以需要到IServiceManager里面去看看是如何实现的4 IServiceManager类frameworksnativeincludebinderIServiceManager.h:IServiceManager是一个抽象类:class IServiceManager : public IInterfacepublic: /宏声明 DECLARE_META_INTERFACE(ServiceManager); virtual sp getService( const String16& name) const = 0; virtual status_t addService( const String16& name, const sp& service, bool allowIsolated = false) = 0; DECLARE_META_INTERFACE声明:#define DECLARE_META_INTERFACE(INTERFACE) static const android:String16 descriptor; static android:sp asInterface( const android:sp& obj); virtual const android:String16& getInterfaceDescriptor() const; I#INTERFACE(); virtual I#INTERFACE(); 替换成IServiceManager:/实现时传入:android.os.IServiceManagerstatic const android:String16 descriptor; static android:sp asInterface( const android:sp& obj); virtual const android:String16& getInterfaceDescriptor() const; /构造析构函数IServiceManager(); virtual IServiceManager(); 实现frameworksnativeincludebinderIServiceManager.cpp:IMPLEMENT_META_INTERFACE(ServiceManager, android.os.IServiceManager);IMPLEMENT_META_INTERFACE实现:看一下asInterface接口:#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) android:sp I#INTERFACE:asInterface( const android:sp& obj) android:sp intr; if (obj != NULL) intr = static_cast( obj-queryLocalInterface( I#INTERFACE:descriptor).get(); if (intr = NULL) intr = new Bp#INTERFACE(obj); return intr; 替换成IServiceManager:android:sp IServiceManager:asInterface( const android:sp& obj) /obj BpBinder实例 android:sp intr; if (obj != NULL) /返回NULL intr = static_cast( obj-queryLocalInterface( IServiceManager:descriptor).get(); if (intr = NULL) intr = new BpServiceManager(obj); return intr; 这里得到IServiceManager 实例:BpServiceManager:new BpServiceManager(new BpBinder(0);5 BpServiceManager 和 BpInterface类frameworksnativelibsbinder IServiceManager.cpp:BpServiceManagerclass BpServiceManager : public BpInterfacepublic: /impl就是 new BpBinder(0) BpServiceManager(const sp& impl) : BpInterface(impl) virtual sp checkService(const String16& name) const remote()-transact(CHECK_SERVICE_TRANSACTION, data, &reply); virtual status_t addService(const String16& name, const sp& service, bool allowIsolated) remote()-transact(ADD_SERVICE_TRANSACTION, data, &reply); frameworksnativeincludebinder IInterface.h:模板类BpInterfacetemplateclass BpInterface : public INTERFACE, public BpRefBase / INTERFACE IServiceManagerpublic:BpInterface(const sp& remote);protected:virtual IBinder* onAsBinder();BpInterface构造函数:templateinline BpInterface:BpInterface(const sp& remote): BpRefBase(remote)BpRefBase构造函数:BpRefBase:BpRefBase(const sp& o): mRemote(o.get(), mRefs(NULL), mState(0)/ IBinder mRemote 指向 o.get() :new BpBinder(0)gDefaultServiceManager = interface_cast(BpBinder(0);实际为:gDefaultServiceManager = new BpServiceManager(new BpBinder(0);Bn代表Binder Native Bp代表Binder ProxyBpServiceManager代理的BpBinder实例 BpBinder代理的handle(0)这个关系有些复杂,看一下类继承结构图:上面这个结构看起来感觉很熟悉Bridge模式。将Binder数据交互和功能处理桥接起来。在Media Process 的main函数中通过:sp sm = defaultServiceManager();我们得到了sm:是BpServiceManager对象。三 MediaPlayerService加入到ServiceManager中回到main函数中:int main(int argc, char* argv) /创建ProcessState 当前进程属性 sp proc(ProcessState:self(); /IServiceManager对象 sp sm = defaultServiceManager(); /初始化MediaPlayerService服务对象 MediaPlayerService:instantiate(); /执行到这里 /启动进程的线程池 ProcessState:self()-startThreadPool(); /执行线程消息循环 IPCThreadState:self()-joinThreadPool();1 MediaPlayerService初始化过程void MediaPlayerService:instantiate() / defaultServiceManager就是上面所述得到的BpServiceManager对象defaultServiceManager()-addService(String16(media.player), new MediaPlayerService();BpServiceManager添加Service:virtual status_t addService(const String16& name, const sp& service, bool allowIsolated) /生成数据包Parcel Parcel data, reply; / Write RPC headers 写入Interface名字 得到“android.os.IServiceManager” data.writeInterfaceToken(IServiceManager:getInterfaceDescriptor(); /写入Service名字 “media.player” data.writeString16(name); /写入服务 data.writeStrongBinder(service); data.writeInt32(allowIsolated ? 1 : 0); / remote()返回BpBinder对象 status_t err = remote()-transact(ADD_SERVICE_TRANSACTION, data, &reply); return err = NO_ERROR ? reply.readExceptionCode() : err;remote()-transact 到BpBinder中:status_t BpBinder:transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)if (mAlive) /到当前进程IPCThreadState中 mHandle=0 status_t status = IPCThreadState:self()-transact( mHandle, code, data, reply, flags); if (status = DEAD_OBJECT) mAlive = 0; return status; return DEAD_OBJECT;2 IPCThreadState中写入数据到Binder设备过程IPCThreadState:self()-transact过程:status_t IPCThreadState:transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) status_t err = data.errorCheck(); flags |= TF_ACCEPT_FDS; /将数据转化成binder_transaction_data 写入到Parcel实例mOut中 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); /写入数据 err = waitForResponse(reply); return err; status_t IPCThreadState:waitForResponse(Parcel *reply, status_t *acquireResult) while (1) /将数据写入到Binder设备中 talkWithDriver(); return err;status_t IPCThreadState:talkWithDriver(bool doReceive) /将数据封装成binder_write_read结构 binder_write_read bwr; do /将数据写入到所打开的Binder设备中 ioctl(mProcess-mDriverFD, BINDER_WRITE_READ, &bwr) while (err = -EINTR); return NO_ERROR;将MediaPlayerService加入到ServiceManager中,这里就通过BpServiceManager的AddService将数据写入到Binder设备传递给ServiceManager。继续Media Process过程四 Media Process消息循环int main(int argc, char* argv) /启动进程的线程池 ProcessState:self()-startThreadPool(); /走到了这里 /执行线程消息循环 IPCThreadState:self()-joinThreadPool();1 创建工作者线程startThreadPool:frameworksnativelibsbinder ProcessState.cpp:void ProcessState:startThreadPool() spawnPooledThread(true);void ProcessState:spawnPooledThread(bool isMain) /创建PoolThread对象 并run ,非线程 sp t = new PoolThread(isMain);t-run(buf);PoolThread继承Thread执行Thread的run函数:status_t Thread:run(const char* name, int32_t priority, size_t stack) /创建线程mThread _threadLoop bool res; res = createThreadEtc(_threadLoop, this, name, priority, stack, &mThread); return NO_ERROR;现在有两个线程:主线程和mThread线程mThread线程执行:_threadLoopint Thread:_threadLoop(void* user) Thread* const self = static_cast(user); do /调用子类的threadLoop result = self-threadLoop(); while(strong != 0); return 0;class PoolThread : public Threadprotected: virtual bool threadLoop() IPCThreadState:self()-joinThreadPool(mIsMain); return false; ;2 进程间通信消息循环过程消息循环:void IPCThreadState:joinThreadPool(bool isMain) mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); status_t result; /消息循环 do int32_t cmd; /从binder设备中读取命令 result = talkWithDriver(); if (result = NO_ERROR) cmd = mIn.readInt32(); /执行命令 result = executeCommand(cmd); while (result != -ECONNREFUSED & result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false);命令执行:status_t IPCThreadState:executeCommand(int32_t cmd) BBinder* obj; RefBase:weakref_type* refs; switch (cmd) case BR_DECREFS: break; case BR_ATTEMPT_ACQUIRE: break;case BR_TRANSACTION:binder_transaction_data tr; result = mIn.read(&tr, sizeof(tr); if (tr.target.ptr) /将目标对象转化成BBinder sp b(BBinder*)tr.cookie); /调用BBinder的transact 函数 const status_t error = b-transact(tr.code, buffer, &reply, tr.flags); break; default: return result;binder_transaction_data.cookie:target object cookie目标对象,这个target object是指那个呢?在Media Process里面有几个Service:AudioFlinger、MediaPlayerService、CameraService等。这个目标是这其中Service中的一个,假设目标对象为为MediaPlayerService,那为何要转化成BBinder呢?3 Service对命令的处理线程从binder接收到消息命令,将命令传递给Service处理。将目标对象转化成BBinder,然后调度此命令;命令从远端传递到本地端进行处理,每个Service都对应BnXXX对象来处理远端BpXXX传来的命令。sp b(BBinder*)tr.cookie);const status_t error = b-transact(tr.code, buffer, &reply, tr.flags);这里b代表某个Service:假设为MediaPlayerService;弄清楚执行过程,要弄清楚类继承关系。本地端BnMediaPlayerService消息处理过程:真正的对象是MediaPlayerService实例。从BBinder -transact开始传递:status_t BBinder:transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) /onTransact是个virtual函数 派生类BnMediaPlayerService重写 err = onTransact(code, data, reply, flags); return err;status_t BnMediaPlayerService:onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) switch (code) case CREATE: pid_t pid = data.readInt32(); sp client = interface_cast(data.readStrongBinder(); /create是个virtual函数 派生类MediaPlayerService重写 sp player = create(pid, client, audioSessionId); /创建player写入到数据包中 传回 reply-writeStrongBinder(player-asBinder(); return NO_ERROR; break; default: return BBinder:onTransact(code, data, reply, flags); 可以看看Client类继承关系结构图:看到这个跟上面的MediaPlayerService继承关系非常的相似,这个结构也非常的熟悉Adapter模式;将binder消息交互和命令处理适配到一起。五 Client端与Service端交互Client对Service进行使用Binder通信,是得到一个Service BnXXX端对象的代理,在Client 为BpXXX代理,然后使用此代理进行相关的操作. 前面在使用ServiceManager就是此种方式进行。实际上通信的基础是Binder,Proxy不过是在Binder上进行了一层封装,封装了对binder驱动的底层操作,使具有面向对象的特性。任意两个进程通过Binder进行通信,就是先得到另一个进程的binder标识,通过此binder进行数据交换。1 新增加一个服务看下面media Palyer类继承结构。实现Bn端类继承结构:实现Bp端类继承结构:可以看到 : 需要定义服务公共接口IMediaPlayerService; 实现服务Bn端 派发消息BnMediaPlayerService; 实现服务的命令处理MediaPlayerService; 实现服务代理BpMediaPlayerService;2 Client获取Service服务Native Service以及framework Service都是加入到ServiceManger中,不管native端还是Framework端得Service
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 某造船厂涂装作业安全办法
- 某化工企业安全操作办法
- 化工厂生产安全管理准则
- 某食品厂添加剂管理
- 某制药厂车间洁净规则
- 某食品厂安全准则
- 矽肺职业病防治
- 腰部术后康复指导
- 2026年家庭过山车能耗优化方案
- 2025年失业挑战与机遇
- 长征名著试题及答案
- 超市会员管理制度方案
- 显示器件制造中的工艺参数优化考核试卷
- 首都经济贸易大学《贝叶斯统计》2021-2022学年第一学期期末试卷
- 病理生理学(南华大学)知到智慧树章节答案
- 客房服务员理论知识考试题及答案
- 上海市人教版七年级下册期末生物期末试卷及答案
- NBT 35091-2016 水电工程生态流量计算规范
- JBT 6434-2024 输油齿轮泵(正式版)
- 建筑施工风险分级管控建筑施工安全生产风险分级管控制度
- 《秋夜》鲁迅作品讲练课件
评论
0/150
提交评论