Android------Binder natvite层架构浅析
来源:互联网 发布:剑灵帅气灵男捏脸数据 编辑:程序博客网 时间:2024/06/06 20:41
提示:源码android7.1
这篇文章我会讲解一下c++层的binder架构,我会把我知道的重要知识点都讲出来,希望对binder不太熟悉的朋友有些许帮助。
先列举一下我会说到的文件,讲到该文件时我就不再列举路径了:
framework/native/include/binder/IBinder.h
framework/native/include/binder/Binder.h
framework/native/include/binder/IInterface.h
framework/native/include/binder/BpBinder.h
framework/native/include/binder/IPCThreadState.h
framework/native/include/binder/IServiceManager.h
framework/native/include/binder/ProcessState.h
framework/native/libs/binder/Binder.cpp
framework/native/libs/binder/BpBinder.cpp
framework/native/libs/binder/IInterface.cpp
framework/native/libs/binder/IPCThreadState.cpp
framework/native/libs/binder/ProcessState.cpp
framework/native/libs/binder/IServiceManager.cpp
下面我先给出一张图:
RefBase从字面上是“引用基类”的意思,为什么它在金字塔的顶层了。
这里我要科普一下,看过Android源码中的c++代码,一定不会对sp/wp感到陌生,系统中有大量的sp/wp,在android系统中,通过RefBase,sp(strong pointer)/wp(weak pointer)这一系列强弱引用计数(也可以叫智能指针),可以实现对对象生命周期的管理。
它们所在的文件如下:
system/core/libutils/RefBase.cpp
system/core/include/utils/RefBase.h
system/core/include/utils/StrongPointer.h
使用引用计数的原因有2个:1是为了防止内存泄露,2是为了避免野指针。
如何使用引用计数,假设现在有一个类,如果要用智能指针来引用这个类的对象,必须满足一下2点:
(1)这个类必须是基类RefBase的子类或者间接子类。
(2)这个类必须定义虚析构函数,比如:virtual ~myClass();
RefBase就讲这么多了,毕竟它不是我们关注的重点,回到binder的分析,这张图里的类都很重要,里面有的类里含有xxx,这是要我们自己去定义的,比如xxx=myService,替代进去就可以了。
我这里要借鉴刘超大神的书中所说把binder涉及到的对象进行一下分类,便于下面的讲解:
(1)Binder实体对象:Binder实体对象就是Binder服务的提供者,”Binder实体对象“对应的是“BBinder 对象"
(2)Binder引用对象:Binder引用对象是Binder实体对象在客户端进程的代表,每个引用对象的类型都是BpBinder类,以名称”BpBinder 对象“来代替”Binder引用对象“
(3)Binder代理对象:也可以叫做Binder接口对象,它主要是为客户端的上层应用提供接口服务,从IInterface派生,它实现Binder服务的函数接口,当然只是一个转掉的空壳,通过代理对象,应用能像使用本地对象一样使用远端的实体对象提供的服务。
(4)IBinder对象,BBinder和BpBinder都是从IBinder类派生,其实不用刻意的去区分引用对象和实体对象,可以用”IBinder“来统一称呼。
这里我把我文章的讲解的内容这里梳理一下:
1.讲解一下binder的大致框架
2.讲解一下server和client获得servicemanager接口的过程
3.提一下java层的BinderService
1》讲一下binder的大体框架
1,IBinder,BBinder,BpBinder
在c++层次我们就能看到binder的主要一些核心类了,BBinder和BpBinder都由IBinder派生,下面我把IBinder.h的部分内容贴出来:
class IBinder : public virtual RefBase{public: enum { FIRST_CALL_TRANSACTION = 0x00000001, LAST_CALL_TRANSACTION = 0x00ffffff, PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'), DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'), SHELL_COMMAND_TRANSACTION = B_PACK_CHARS('_','C','M','D'), INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'), SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'), // Corresponds to TF_ONE_WAY -- an asynchronous call. FLAG_ONEWAY = 0x00000001 }; IBinder(); /** * Check if this IBinder implements the interface named by * @a descriptor. If it does, the base pointer to it is returned, * which you can safely static_cast<> to the concrete C++ interface. */ virtual sp<IInterface> queryLocalInterface(const String16& descriptor); /** * Return the canonical name of the interface provided by this IBinder * object. */ virtual const String16& getInterfaceDescriptor() const = 0; virtual bool isBinderAlive() const = 0; virtual status_t pingBinder() = 0; virtual status_t dump(int fd, const Vector<String16>& args) = 0; static status_t shellCommand(const sp<IBinder>& target, int in, int out, int err, Vector<String16>& args, const sp<IResultReceiver>& resultReceiver); virtual status_t transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) = 0; class DeathRecipient : public virtual RefBase { public: virtual void binderDied(const wp<IBinder>& who) = 0; }; /** * Register the @a recipient for a notification if this binder * goes away. If this binder object unexpectedly goes away * (typically because its hosting process has been killed), * then DeathRecipient::binderDied() will be called with a reference * to this. * * The @a cookie is optional -- if non-NULL, it should be a * memory address that you own (that is, you know it is unique). * * @note You will only receive death notifications for remote binders, * as local binders by definition can't die without you dying as well. * Trying to use this function on a local binder will result in an * INVALID_OPERATION code being returned and nothing happening. * * @note This link always holds a weak reference to its recipient. * * @note You will only receive a weak reference to the dead * binder. You should not try to promote this to a strong reference. * (Nor should you need to, as there is nothing useful you can * directly do with it now that it has passed on.) */ virtual status_t linkToDeath(const sp<DeathRecipient>& recipient, void* cookie = NULL, uint32_t flags = 0) = 0; /** * Remove a previously registered death notification. * The @a recipient will no longer be called if this object * dies. The @a cookie is optional. If non-NULL, you can * supply a NULL @a recipient, and the recipient previously * added with that cookie will be unlinked. */ virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, void* cookie = NULL, uint32_t flags = 0, wp<DeathRecipient>* outRecipient = NULL) = 0; virtual bool checkSubclass(const void* subclassID) const; typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie); virtual void attachObject( const void* objectID, void* object, void* cleanupCookie, object_cleanup_func func) = 0; virtual void* findObject(const void* objectID) const = 0; virtual void detachObject(const void* objectID) = 0; virtual BBinder* localBinder(); virtual BpBinder* remoteBinder();protected: virtual ~IBinder();private:};我们看到在IBinder中有很多纯虚函数,也就是说IBinder是一个抽象类,是不能实例化的,所以必须要有派生类,而BBinder和BpBinder就出现了,它两都继承了IBInder,并且把这些纯虚函数都重写了,所以BBinder和BpBinder是可以实例化的,这里还要注意IBinder是可以使用应用计数的,也就是用智能指针来管理它的对象,也就是BpBinder和BBinder的对象。这里有两个函数,localBinder和remoteBinder,用它们可以得到BBinder和BpBinder,看函数意思也知道,一个得到本地实体对象,一个是得到引用对象。
2.IInterface,BnInterface,BpInterface
下面介绍一下IInterface以及他的两个派生类:BnInterface和BpInterface
首先看一下Interface.h,节选一些代码贴出来:
class IInterface : public virtual RefBase{public: IInterface(); static sp<IBinder> asBinder(const IInterface*); static sp<IBinder> asBinder(const sp<IInterface>&);protected: virtual ~IInterface(); virtual IBinder* onAsBinder() = 0;};// ----------------------------------------------------------------------template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}template<typename INTERFACE>class BnInterface : public INTERFACE, public BBinder{public: virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); virtual const String16& getInterfaceDescriptor() const;protected: virtual IBinder* onAsBinder();};// ----------------------------------------------------------------------template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public: BpInterface(const sp<IBinder>& remote);protected: virtual IBinder* onAsBinder();};#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(); \#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \ const android::String16 I##INTERFACE::descriptor(NAME); \ const android::String16& \ I##INTERFACE::getInterfaceDescriptor() const { \ return I##INTERFACE::descriptor; \ } \ android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ const android::sp<android::IBinder>& obj) \ { \ android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == NULL) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ } \ I##INTERFACE::I##INTERFACE() { } \ I##INTERFACE::~I##INTERFACE() { } ......template<typename INTERFACE>inline IBinder* BpInterface<INTERFACE>::onAsBinder(){ return remote();}......
看IInterface的定义知道,它也是可以使用引用计数的,并且他也是一个抽象类,BnInterface和BpInterface都继承了它,并且实现了它的纯虚函数onAsBinder
这里不同的是BnInterface它还继承与BBinder,而BpInterface另一个继承对象为BpRefBase,这里为什么要这样设计了,先看一下BpRefbase
class BpRefBase : public virtual RefBase{protected: BpRefBase(const sp<IBinder>& o); virtual ~BpRefBase(); virtual void onFirstRef(); virtual void onLastStrongRef(const void* id); virtual bool onIncStrongAttempted(uint32_t flags, const void* id); inline IBinder* remote() { return mRemote; } inline IBinder* remote() const { return mRemote; }private: BpRefBase(const BpRefBase& o); BpRefBase& operator=(const BpRefBase& o); IBinder* const mRemote; RefBase::weakref_type* mRefs; std::atomic<int32_t> mState;};我们看到在BpRefBase内部是有一个mRemote成员的,它是一个指向IBinder的指针。因为BpInterface继承了BpRefBase,所以BpInterface先天就内置了一个mRemote成员,
这个mRemote记录的其实就是BpBinder对象,不让BpInterface直接继承BpBinder是为了让开发更加灵活,同时Binder的内部实现和上层完全隔开了,用户完全不知道BpBinder的存在。
在实际的开发中,我们完全可以创建多个聚合同一BpBinder的代理对象,这个代理对象其实对应着同一个远端binder实体,用户可以创建很多个代理对象(也叫代理接口)也意为着方便了用户的使用。
在编写c++层的binder时,BpInterface和BnInterface都是用户需要去继承的类,它们是代理对象,也是直接交互的对象。
3,DECLARE_META_INTERFACE,IMPLEMENT_META_INTERFACE
下面我要提一下2个重要的宏,android巧妙的通过DECLARE_META_INTERFACE(INTERFACE)和IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 将通信和业务牢牢的栓在了一起。这2个宏我刚才已经贴出来了,也是在IInterface.h中。这里只有告你大家这2个宏很重要,具体的分析在下面我会讲到。
4,ProcessState
每个进程只有一个ProcessState,它是独一无二的,ProcessState的字面意思就是进程状态,来看下ProcessState的定义,在ProcessState.h中
class ProcessState : public virtual RefBase{public: static sp<ProcessState> self(); void setContextObject(const sp<IBinder>& object); sp<IBinder> getContextObject(const sp<IBinder>& caller); void setContextObject(const sp<IBinder>& object, const String16& name); sp<IBinder> getContextObject(const String16& name, const sp<IBinder>& caller); void startThreadPool(); typedef bool (*context_check_func)(const String16& name, const sp<IBinder>& caller, void* userData); bool isContextManager(void) const; bool becomeContextManager( context_check_func checkFunc, void* userData); sp<IBinder> getStrongProxyForHandle(int32_t handle); wp<IBinder> getWeakProxyForHandle(int32_t handle); void expungeHandle(int32_t handle, IBinder* binder); void spawnPooledThread(bool isMain); status_t setThreadPoolMaxThreadCount(size_t maxThreads); void giveThreadPoolName();private: friend class IPCThreadState; ProcessState(); ~ProcessState(); ProcessState(const ProcessState& o); ProcessState& operator=(const ProcessState& o); String8 makeBinderThreadName(); struct handle_entry { IBinder* binder; RefBase::weakref_type* refs; }; handle_entry* lookupHandleLocked(int32_t handle); int mDriverFD; void* mVMStart; // Protects thread count variable below. pthread_mutex_t mThreadCountLock; pthread_cond_t mThreadCountDecrement; // Number of binder threads current executing a command. size_t mExecutingThreadsCount; // Maximum number for binder threads allowed for this process. size_t mMaxThreads; // Time when thread pool was emptied int64_t mStarvationStartTimeMs; mutable Mutex mLock; // protects everything below. Vector<handle_entry>mHandleToObject; bool mManagesContexts; context_check_func mBinderContextCheckFunc; void* mBinderContextUserData; KeyedVector<String16, sp<IBinder> > mContexts; String8 mRootDir; bool mThreadPoolStarted; volatile int32_t mThreadPoolSeq;};ProcessState中有一个mDriverFD,这个值用来记录binder驱动对应的句柄值,以便随时和binder驱动通信,ProcessState采用了单例模式,来看它的ProcessState.cpp:
sp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess;}ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) , mThreadCountDecrement(PTHREAD_COND_INITIALIZER) , mExecutingThreadsCount(0) , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) , mStarvationStartTimeMs(0) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1){ if (mDriverFD >= 0) { // mmap the binder, providing a chunk of virtual address space to receive transactions. mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } } LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");}
ProcessState在构造时会打开binder驱动,而且如果mDriverFD>0(也就是说不是servicemanager)就对打开的驱动文件进行内存映射操作。ProcessState中还有一个mHandleToObject比较有用,它是该进程中记录所有BpBinder的表,
5.IPCThreadState
IPCThreadState和驱动之间耦合的很厉害,BpBinder会和IPCThreadState打交道,然后IPCThreadState就和驱动打交道。我们知道借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员,友元类中的所有成员函数都是另外一个类的友元函数,在上面ProcessState中可以看到,IPCThreadState被声明为了ProcessState的友元类,也就是说IPCThreadState中的所有函数都可以访问ProcessState的private成员。
2》server和client获取servicemanager接口的过程
先看一下servicemanager的关系图,实际上系统中只有Iservicemanager,BpServiceManger,系统中并没有BnServiceManger,那是因为android弄了一个service_manager.c来充当BnServiceManager的角色,在servicemanager篇中我么已经说过这个它的main函数了。
获取servicemanager远程接口的函数是defaultServiceManager,在Iservicemanager..cpp中
sp<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); while (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); if (gDefaultServiceManager == NULL) sleep(1); } } return gDefaultServiceManager;}
其中gDefaultServiceManager定义在Static.cpp中sp<IServiceManager> gDefaultServiceManager;
从defaultServiceManager函数看出gDefaultServiceManager是单例模式,该函数中最重要的一句就是
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
我们仔细分析一下,首先通过ProcessState::self()得到一个ProcessState的单例对象gProcess,ProcessState在创建的时候会通过open函数打开驱动文件/dev/binder/,并且将返回的设备描述符保存在mDriverFD中。然后调用得到的gProcess的getContextObject函数
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){ return getStrongProxyForHandle(0);}继续跟踪getStrongProxyForHandle(0)
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){spresult; 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) { Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; } b = new BpBinder(handle); e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else {result.force_set(b); e->refs->decWeak(this); } } return result;}
这里生成了BpBInder(0),于是上面的代码变成了gDefaultServiceManager = interface_cast<IServiceManager>(BpBInder(0));
接着看interface_cast函数,实际上它是一个很重要的类型转换函数,在IInterface.h中,
template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}即调用了IServiceManager:asInterface(BpBinder(0));
还记得上面的IMPLEMENT_META_INTERFACE宏吗,该asInterface函数就是在这个宏里面定义的
IServiceManager具体的定义如下
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
android::sp<I##INTERFACE> I##INTERFACE::asInterface( \ const android::sp<android::IBinder>& obj) \ { \ android::sp<I##INTERFACE> intr; \ if (obj != NULL) { \ intr = static_cast<I##INTERFACE*>( \ obj->queryLocalInterface( \ I##INTERFACE::descriptor).get()); \ if (intr == NULL) { \ intr = new Bp##INTERFACE(obj); \ } \ } \ return intr; \ }这里传进来的obj参数为BpBinder(0),INTERFACE为IServiceManager,
这里BpBinder(0)->queryLocalInterface会调用IBinder的queryLocalInterface
sp<IInterface> IBinder::queryLocalInterface(const String16& /*descriptor*/){ return NULL;}那么这里intr==null
intr = new BpServiceManager(BpBinder(0))
这样ServiceManager的远程接口就创建完成了,它其实是一个BpServiceManager,包含了一个句柄值为0的BpBinder引用对象
3》其实Binder服务可以分为2种,一种是实名服务,一种是匿名服务,它们从开发到使用没有任何区别,唯一的区别是实名服务可以用servicemanager查找到,如ActivityManagerService,PowerManagerService,匿名服务不能用servicemanager查找到,比如frameworks层提供的一种启动java匿名binder服务的方法:
首先某个应用通过调用binderService方法发出一个intent,Framework根据intent找到对应的组件service并启动它,包含在service中的binder服务也同时创建出来,随后,framework会把服务的IBinder对象通过ConnectivityManager的回调方法onServiceConnected传回到应用,这样应用客户端就得到匿名BInder服务的引用对象,也就能使用组件Service中的匿名BInder服务了,在这里Frameworks中的Intent代替了Binder服务的名称来查找对应的服务,同时也承担了ServiceManager的工作。
参考文献:《深入解析Android5.0系统》;《Android开发艺术探索》;《深入理解Android卷1》;《深入理解Android卷3》;红茶一杯话binder------点击打开链接;gityuan的binder系列------点击打开链接;罗升阳的binder系列------点击打开链接;Andriod Binder机制------点击打开链接;Android深入浅出之binder机制------点击打开链接;理解Android的binder机制-----点击打开链接;轻松理解Androidbinder------点击打开链接;binder service入门------点击打开链接
- Android------Binder natvite层架构浅析
- Android------Binder java层浅析
- Android之Binder浅析
- Android之Binder浅析
- Android之Binder浅析
- 浅析Android binder机制
- Android Binder机制浅析
- 浅析Android binder机制
- Android Binder机制浅析
- android binder 浅析
- 浅析Android binder机制
- Android--Binder驱动浅析
- Android Binder机制浅析
- Android Binder机制浅析
- Android Binder机制浅析
- Android Binder机制浅析
- Android binder系统架构
- Android binder系统架构
- ViewPager设置焦点的问题
- ECMAScript6(ES6)新特性
- struts配置说明
- android 自动化测试--robotium使用,可以用来做自动化、单元测试等一系列测试
- 141. Linked List Cycle (链表)
- Android------Binder natvite层架构浅析
- 暑期学习 GAN 笔记
- Summer sell-off (Codeforces-810B)
- Python进行特征提取
- 排列组合(三)
- JAVA开发的23种设计模式之 — 责任链模式
- 单向链表-创建
- Java读取文件----中文乱码问题
- Java基础对象、bean、spring boot