//frameworks/base/core/java/android/os/ServiceManager.javapublicstaticvoidaddService(Stringname,IBinderservice){try{getIServiceManager().addService(name,service,false);//添加服务}catch(RemoteExceptione){Log.e(TAG,"error in addService",e);}}
//frameworks/base/core/java/android/os/ServiceManager.javaprivatestaticHashMap<String,IBinder>sCache=newHashMap<String,IBinder>();//缓存publicstaticIBindergetService(Stringname){try{IBinderservice=sCache.get(name);//查询缓存if(service!=null){returnservice;//从缓存中查到结果,直接返回}else{returngetIServiceManager().getService(name);//向SM发起查询}}catch(RemoteExceptione){Log.e(TAG,"error in getService",e);}returnnull;}
privatestaticIServiceManagergetIServiceManager(){if(sServiceManager!=null){returnsServiceManager;}// Find the service manager//调用BinderInternal获取IBindersServiceManager=ServiceManagerNative.asInterface(BinderInternal.getContextObject());returnsServiceManager;}
//frameworks/base/core/java/android/os/ServiceManagerNative.javapublicstaticIServiceManagerasInterface(IBinderobj){if(obj==null){returnnull;}// ServiceManager is never localreturnnewServiceManagerProxy(obj);}
jobjectjavaObjectForIBinder(JNIEnv*env,constsp<IBinder>&val){if(val==NULL)returnNULL;if(val->checkSubclass(&gBinderOffsets)){// One of our own!jobjectobject=static_cast<JavaBBinder*>(val.get())->object();LOGDEATH("objectForBinder %p: it's our own %p!\n",val.get(),object);returnobject;}// For the rest of the function we will hold this lock, to serialize// looking/creation/destruction of Java proxies for native Binder proxies.AutoMutex_l(mProxyLock);// Someone else's... do we know about it?jobjectobject=(jobject)val->findObject(&gBinderProxyOffsets);if(object!=NULL){jobjectres=jniGetReferent(env,object);if(res!=NULL){ALOGV("objectForBinder %p: found existing %p!\n",val.get(),res);returnres;}LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!",object,val.get());android_atomic_dec(&gNumProxyRefs);val->detachObject(&gBinderProxyOffsets);env->DeleteGlobalRef(object);}//创建BinderProxy对象object=env->NewObject(gBinderProxyOffsets.mClass,gBinderProxyOffsets.mConstructor);if(object!=NULL){LOGDEATH("objectForBinder %p: created new proxy %p !\n",val.get(),object);// The proxy holds a reference to the native object.env->SetLongField(object,gBinderProxyOffsets.mObject,(jlong)val.get());val->incStrong((void*)javaObjectForIBinder);// The native object needs to hold a weak reference back to the// proxy, so we can retrieve the same proxy if it is still active.jobjectrefObject=env->NewGlobalRef(env->GetObjectField(object,gBinderProxyOffsets.mSelf));val->attachObject(&gBinderProxyOffsets,refObject,jnienv_to_javavm(env),proxy_cleanup);// Also remember the death recipients registered on this proxysp<DeathRecipientList>drl=newDeathRecipientList;drl->incStrong((void*)javaObjectForIBinder);env->SetLongField(object,gBinderProxyOffsets.mOrgue,reinterpret_cast<jlong>(drl.get()));// Note that a new object reference has been created.android_atomic_inc(&gNumProxyRefs);incRefsCreated(env);}returnobject;}
//构造函数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){//成功打开/dev/binder// 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.");}
staticintopen_driver(){intfd=open("/dev/binder",O_RDWR|O_CLOEXEC);if(fd>=0){intvers=0;status_tresult=ioctl(fd,BINDER_VERSION,&vers);//获取实现的版本号if(result==-1){ALOGE("Binder ioctl to obtain version failed: %s",strerror(errno));close(fd);fd=-1;}if(result!=0||vers!=BINDER_CURRENT_PROTOCOL_VERSION){ALOGE("Binder driver protocol does not match user space protocol!");close(fd);fd=-1;}size_tmaxThreads=DEFAULT_MAX_BINDER_THREADS;result=ioctl(fd,BINDER_SET_MAX_THREADS,&maxThreads);if(result==-1){ALOGE("Binder ioctl to set max threads failed: %s",strerror(errno));}}else{ALOGW("Opening '/dev/binder' failed: %s\n",strerror(errno));}returnfd;}
sp<IBinder>ProcessState::getStrongProxyForHandle(int32_thandle){sp<IBinder>result;AutoMutex_l(mLock);//查找handle对应的资源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)){if(handle==0){// Special case for context manager...// The context manager is the only object for which we create// a BpBinder proxy without already holding a reference.// Perform a dummy transaction to ensure the context manager// is registered before we create the first local reference// to it (which will occur when creating the BpBinder).// If a local reference is created for the BpBinder when the// context manager is not present, the driver will fail to// provide a reference to the context manager, but the// driver API does not return status.//// Note that this is not race-free if the context manager// dies while this code runs.//// TODO: add a driver API to wait for context manager, or// stop special casing handle 0 for context manager and add// a driver API to get a handle to the context manager with// proper reference counting.Parceldata;//测试Binder是否就绪status_tstatus=IPCThreadState::self()->transact(0,IBinder::PING_TRANSACTION,data,NULL,0);if(status==DEAD_OBJECT)returnNULL;}b=newBpBinder(handle);//创建BpBindere->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);}}returnresult;}