native binder相关类
来源:互联网 发布:淘宝店铺四钻能卖多少 编辑:程序博客网 时间:2024/05/06 07:45
android native binder相关的类在/frameworks/native/libs/binder/目录下,对应的头文件在/frameworks/native/include/binder/目录下。不同版本的源码,路径可能会有不同。
1、ProcessState.cpp
ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1){ if (mDriverFD >= 0) { // XXX Ideally, there should be a specific define for whether we // have mmap (or whether we could possibly have the kernel module // availabla). // 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 driver(/dev/binder),保存fd到mDriverFD,然后mmap创建了共享内存,并将内存指针保存到mVMStart。通过mmap,将这个虚拟设备/dev/binder的fd映射到了内存,这样内存操作就相当于read/write fd了。在打开binder driver时,ioctl比较了BINDER_CURRENT_PROTOCOL_VERSION并设置了BINDER_SET_MAX_THREADS。
sp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess;}
外部直接访问ProcessState::self()方法直接获取到ProcessState对象。
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){ return getStrongProxyForHandle(0);}sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) // XXX: handle == 0{ sp<IBinder> result; AutoMutex _l(mLock); // handle_entry定义 // struct handle_entry { // IBinder* binder; // RefBase::weakref_type* refs; // }; handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { // We need to create a new BpBinder if there isn't currently one, OR we // are unable to acquire a weak reference on this current one. See comment // in getWeakProxyForHandle() for more info about this. IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { b = new BpBinder(handle); // XXX: handler == 0 e->binder = b; if (b) e->refs = b->getWeakRefs(); result = b; } else { // This little bit of nastyness is to allow us to add a primary // reference to the remote proxy when this team doesn't have one // but another team is sending the handle to us. result.force_set(b); e->refs->decWeak(this); } } return result;}
分析上边的代码,getContextObject()最终返回了一个BpBinder。
void ProcessState::startThreadPool(){ AutoMutex _l(mLock); if (!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true); } }void ProcessState::spawnPooledThread(bool isMain){ if (mThreadPoolStarted) { int32_t s = android_atomic_add(1, &mThreadPoolSeq); char buf[16]; snprintf(buf, sizeof(buf), "Binder_%X", s); ALOGV("Spawning new pooled thread, name=%s\n", buf); sp<Thread> t = new PoolThread(isMain); t->run(buf); }}
ProcessState::startThreadPool()主要是创建并启动了一个PoolThread。
2、BpBinder.cpp
BpBinder::BpBinder(int32_t handle) // XXX: handle == 0 : mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(NULL){ ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); extendObjectLifetime(OBJECT_LIFETIME_WEAK); // incWeakHandle()最终会在IPCThreadState的mOut中写入一个命令,并在flushCommond()时执行 IPCThreadState::self()->incWeakHandle(handle);}status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ // Once a binder 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; } return DEAD_OBJECT;}
BpBinder实现了IBinder接口,所以有transact(),linkToDeath(),unlinkToDeath()等方法。基本和java层aidl类中的Proxy内部类方法一样。这几个方法最终都会调用到IPCThreadState的方法中。
另外BpBinder还实现了ObjectManager接口,大概类似与一个map的东东,key是object id,value是一个结构体。
3、Binder.cpp
BBinder::BBinder() : mExtras(NULL){}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;}status_t BBinder::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch (code) { case INTERFACE_TRANSACTION: reply->writeString16(getInterfaceDescriptor()); return NO_ERROR; case DUMP_TRANSACTION: { int fd = data.readFileDescriptor(); int argc = data.readInt32(); Vector<String16> args; for (int i = 0; i < argc && data.dataAvail() > 0; i++) { args.add(data.readString16()); } return dump(fd, args); } case SYSPROPS_TRANSACTION: { report_sysprop_change(); return NO_ERROR; } default: return UNKNOWN_TRANSACTION; }}
Binder也实现了IBinder接口,所以有transact(),linkToDeath(),unlinkToDeath()等方法。linkToDeath(),unlinkToDeath()都是空方法,不执行任何操作。和java层aidl类中的Stub内部类的方法一样。
4、IPCThreadState.cpp
IPCThreadState* IPCThreadState::self(){ if (gHaveTLS) {restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); // 获取gTLS对应的值 if (st) return st; return new IPCThreadState; } if (gShutdown) return NULL; pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { // 创建gTLS线程key,设置线程结束的回调函数 if (pthread_key_create(&gTLS, threadDestructor) != 0) { pthread_mutex_unlock(&gTLSMutex); return NULL; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart;}IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), // 获取到ProcessState对象 mMyThreadId(androidGetTid()), // 获取到tid mStrictModePolicy(0), mLastTransactionBinderFlags(0){ pthread_setspecific(gTLS, this); // 设置gTLS对应的值 clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256);}
IPCThreadState::self()里通过pthread_key_create()创建了线程相关的key(类似java中的ThreadLocal),设置了线程结束时的回调方法threadDestructor(),最终获取到了gTLS对应的IPCThreadState对象。而在IPCThreadState构造方法中使用gTLS将自己保存起来,同时还获取到了ProcessState对象和tid。
void IPCThreadState::joinThreadPool(bool isMain){ LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid()); mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); // This thread may have been spawned by a thread that was in the background // scheduling group, so first we will make sure it is in the foreground // one to avoid performing an initial transaction in the background. set_sched_policy(mMyThreadId, SP_FOREGROUND); status_t result; do { int32_t cmd; // When we've cleared the incoming command queue, process any pending derefs if (mIn.dataPosition() >= mIn.dataSize()) { size_t numPending = mPendingWeakDerefs.size(); if (numPending > 0) { for (size_t i = 0; i < numPending; i++) { RefBase::weakref_type* refs = mPendingWeakDerefs[i]; refs->decWeak(mProcess.get()); } mPendingWeakDerefs.clear(); } numPending = mPendingStrongDerefs.size(); if (numPending > 0) { for (size_t i = 0; i < numPending; i++) { BBinder* obj = mPendingStrongDerefs[i]; obj->decStrong(mProcess.get()); } mPendingStrongDerefs.clear(); } } // now get the next command to be processed, waiting if necessary result = talkWithDriver(); if (result >= NO_ERROR) { size_t IN = mIn.dataAvail(); if (IN < sizeof(int32_t)) continue; cmd = mIn.readInt32(); IF_LOG_COMMANDS() { alog << "Processing top-level Command: " << getReturnString(cmd) << endl; } result = executeCommand(cmd); } // After executing the command, ensure that the thread is returned to the // foreground cgroup before rejoining the pool. The driver takes care of // restoring the priority, but doesn't do anything with cgroups so we // need to take care of that here in userspace. Note that we do make // sure to go in the foreground after executing a transaction, but // there are other callbacks into user code that could have changed // our group so we want to make absolutely sure it is put back. set_sched_policy(mMyThreadId, SP_FOREGROUND); // Let this thread exit the thread pool if it is no longer // needed and it is not the main process thread. if(result == TIMED_OUT && !isMain) { break; } } while (result != -ECONNREFUSED && result != -EBADF); LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n", (void*)pthread_self(), getpid(), (void*)result); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false);}
IPCThreadState::joinThreadPool()主要作用是在一个循环中不断的talkWithDriver()和executeCommond(),从binder driver中读取数据,然后执行命令。
5、IInterface.h
上边的IServiceManager中使用到了interface_cast。我们看看它又是怎么定义的:
template<typename INTERFACE>// 定义interface_castinline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);// 定义descriptor变量,asInterface()、getInterfaceDescriptor()和构造/析构方法#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(); // 定义XXX::descriptor() XXX::getInterfaceDescriptor() XXX::asInterface()和// XXX构造/析构 方法#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() { }
5、IServiceManager.cpp
sp<IServiceManager> defaultServiceManager(){ if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); if (gDefaultServiceManager == NULL) { // 获取一个BpBinder对象的weak reference,并对该对象做了interface_cast // interface_cast在IInterface.h中定义 gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } } return gDefaultServiceManager;}IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
注意,该方法可以得到一个IServiceManager的bp对象,并在在多个系统子服务中都被调用。此处先调用了ProcessState的getContextObject()。在上边的ProcessState代码分析中,getContextObject()最终返回一个handle==0的BpBinder。然后对这个BpBinder做了interface_cast。另外IServiceManager中还定义了checkPermission()方法,最终在IPermissionController中检测权限相关。
在IServiceManager.h中,有这样的宏定义:
DECLARE_META_INTERFACE(ServiceManager);
综合IInterface.h、IServiceManager.cpp中的宏定义和宏使用情况,interface_cast最终会返回Interface的Bp对象。此处,返回的就是一个使用BpBinder(handle==0)创建的BpServiceManager对象。而在BpServiceManager中还定义了addService(),getService(),checkService(),listServicve()等方法,用于添加、获取系统服务等。而这几个方法最终都调用到了remote的transact()方法,再通过binder驱动,最终到了BnServiceManager的onTransact()中。
class BpServiceManager : public BpInterface<IServiceManager>{public: // 。。。。省略 virtual sp<IBinder> checkService( const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); data.writeString16(name); remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); return reply.readStrongBinder(); } // 。。。。省略}status_t BnServiceManager::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ //printf("ServiceManager received: "); data.print(); switch(code) { case GET_SERVICE_TRANSACTION: { CHECK_INTERFACE(IServiceManager, data, reply); String16 which = data.readString16(); sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which); reply->writeStrongBinder(b); return NO_ERROR; } break; case CHECK_SERVICE_TRANSACTION: {} // 。。。。省略 default: return BBinder::onTransact(code, data, reply, flags); }}
- native binder相关类
- Binder In Native
- Native Binder 实例
- Android Native Binder
- Native Binder通讯
- Binder In Native
- Android Binder Native
- Binder(native层)
- Binder通信相关的类简要分析
- binder相关类及成员函数介绍
- Android5.0中Binder机制相关的native层的Parcel分析
- Binder机制3---Native层
- Binder机制3---Native层
- Android创建Native Binder Service
- Binder 通信笔记(native)
- Binder机制3---Native层
- 通过Binder实现 Native Service
- Android5.0中Binder机制相关的native层和java层中的Binder代理和实体的对象的分析
- MPLS/VPN 基本原理及在ZXR10中的配置
- 4Sum
- 飛飛(四十六)交通工具
- LinkedList集合源码解析
- eclipse使用maven搭建spring mvc
- native binder相关类
- JDBC初识
- 数组中只出现一次的数字
- leetcode---Roman to Integer
- HDU 4857 逃生 (反向拓扑排序+优先队列)
- Echarts 使用总结
- 48.leetcode题目17. Letter Combinations of a Phone Number
- leetcode.295. Find Median from Data Stream
- Android adapter设计模式一 静态设值