-
首先需要说明的是,本篇文章是从native层开始进行Service Manager的获取
-
回到Binder的框架图,本质上Service的底层实体就是一个BBinder实体,而Clinet客户端想要调用某个service端,需要拿到对应service端的代理接口,也就是BpBinder对象。
-
如上面的框架图,Client端想要和Service端进行通信,那么就需要使用
defaultServiceManager()
方法获取到IServiceManager
对象,一旦拥有了IServiceManager
对象,那么Client端就可以通过IServiceManager
对象和Service Manager进程进行通信。需要特别说明的是:ServiceManager进程是一个守护进程,通过defaultServiceManager()
方法获取到的是native层的IServiceManager类的一个实例。
Sevice Manager获取解析
Service Manager获取相关图示
-
在正式开始分析代码之前,先放上时序图,并针对时序图做一个简单说明
defaultServiceManager()
会返回一个IServiceManager
强指针对象,而在IServiceManager
类中提供了诸如:getService()
、addService()
等方法- 在该函数中首先会调用
ProcessState::self()
获取到ProcessState对象,该ProcessState对象是采用单例模式创建的;因此,当ProcessState::self()
第一次被调用时,会新建ProcessState对象。在ProcessState的构造函数中,会先通过open_driver()
打开**/dev/binder**,接着调用mmap()
映射内存到当前进程中。此时,ProcessState就初始化完毕,它将**/dev/binder**的文件句柄以及映射内存都保存在自己的私有成员中。 - 在获取到ProcessState对象之后,会通过该对象调用
getContextObject()
来获取一个IBinder对象。getContextObject()
会调用getStrongProxyForHandle(0)
来获取句柄0的强引用代理对象,这里的句柄0被赋予了特殊意义:它就是ServiceManager的句柄。在Binder驱动中,若获取到句柄的值是0,则会将其目标当作是ServiceManager。getStrongProxyForHandle(0)
会先通过lookupHandleLocked()
在ProcessState的矢量数组mHandleToObject中查找句柄为0的对象;找不到的话,则新建句柄为0的对象,并将其添加到mHandleToObject矢量数组中;这样,下次再通过getStrongProxyForHandle()
查找时,就能快速的找到。由此可见,mHandleToObject是ProcessState中保存句柄的缓冲数组。 随后,会新建句柄0所对应的BpBinder对象,BpBinder是IBinder的代理;这里就获取到了ServiceManager的BpBinder代理对象。简而言之,getContextObject()
的目的就是获取ServiceManager对应的BpBinder代理对象。 在新建BpBinder时,会通过IPCThreadState::self()
获得IPCThreadState对象;因为,需要通过IPCThreadState对象来与Binder驱动进行交互。 - 前面已经成功获取到了ServiceManager的BpBinder代理,而
defaultServiceManager()
返回的是IServiceManager对象。这里,使用了一个技巧,通过宏interface_cast而调用asInterface()
函数,从而返回IServiceManager的代理BpServiceManager。到这里,defaultServiceManager()
流程就基本执行完毕了
service Manager代理对象获取代码解析
- 需要说明以下代码分析都是基于Android R版本进行
defaultServiceManager()方法
-
defaultServiceManager()
是native层获取IServiceManager
对象的方法。代码路径:android/framework/native/libs/binder/IServiceManager.cppusing AidlServiceManager = android::os::IServiceManager; sp<IServiceManager> defaultServiceManager() { //首先确保新建操作只会被调用一次 std::call_once(gSmOnce, []() { //将AidlServiceManager对象置空 sp<AidlServiceManager> sm = nullptr; //当sm为空时,不会跳出while循环 while (sm == nullptr) { //创建sm对象 /*这里进行分解: * 1.ProcessState::self() 用来构建出ProcessState对象 * 2.ProcessState->getContextObject(nullptr) 获取到了SM对应的BpBinder对象 * 3.interface_cast<AidlServiceManager>(BpBinder(0)) AidlServiceManager=android::os::IServiceManager * interface_cast经过转化就变成了: * IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); * const android::String16 I##INTERFACE::descriptor("android.os.IServiceManager"); * android::sp<IServiceManager> IServiceManager::asInterface( * const android::sp<android::IBinder>& obj) * { * android::sp<IServiceManager> intr; * //根据BpBinder,去查找"android.os.IServiceManager"的本地接口,如果找不到,那么就已BpBinder为参数新建BpServiceManager,也就是IServiceManager * if (obj != NULL) { * intr = static_cast<IServiceManager*>( * obj->queryLocalInterface( * IServiceManager::descriptor).get()); * if (intr == NULL) { * intr = new BpServiceManager(obj); * } * } * return intr; * } */ sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr)); //如果创建不成功,那么就睡眠1s后再尝试创建,这种情况可能出现在刚开机的时候,过早调用defaultServiceManager方法,导致创建不成功 if (sm == nullptr) { ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str()); sleep(1); } } //根据新建的sm对象,构建出ServiceManagerShim对象----其实就是新建了ServiceManagerShim对象,然后将sm用ServiceManagerShim.mTheRealServiceManager保存了起来 gDefaultServiceManager = new ServiceManagerShim(sm); }); //最后返回gDefaultServiceManager对象,也就是ServiceManagerShim对象 return gDefaultServiceManager; }
-
分析
defaultServiceManager()
内部的代码,主要在做以下几个动作:- 调用
call_once()
确保创建动作只会调用一次 - 存在一个
while
循环,只有在IServiceManager
对象创建成功之后才会退出循环 - 当
IServiceManager
对象没有创建成功,会休眠1s后再去尝试创建,直到创建成功为止
- 调用
-
分析代码可以发现,
IServiceManager
对象的创建是通过interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
实现的,那么我们将其拆分成三个部分ProcessState::self()
ProcessState->getContextObject(nullptr)
interface_cast<AidlServiceManager>()
接下来对其进行逐一分析
-
IServiceManager对象的创建
1. ProcessState::self()
-
代码路径:android/framework/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self() { Mutex::Autolock _l(gProcessMutex); //如果gProcess不为空,那么直接返回gProcess变量 if (gProcess != nullptr) { return gProcess; } //否则新建一个ProcessState对象,并用gProcess保存起来,kDefaultDriver就是binder的驱动名:"/dev/binder" gProcess = new ProcessState(kDefaultDriver); return gProcess; }
self()
方法本质上就是返回了一个ProcessState对象,如果不存在ProcessState对象,那么就调用构造函数进行新建#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) #define DEFAULT_MAX_BINDER_THREADS 15 ProcessState::ProcessState(const char *driver) : mDriverName(String8(driver)) , mDriverFD(open_driver(driver)) //在构建ProcessState时,会调用open_driver()打开对应驱动,这里打开的是/dev/binder , mVMStart(MAP_FAILED) , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) , mThreadCountDecrement(PTHREAD_COND_INITIALIZER) , mExecutingThreadsCount(0) , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) , mStarvationStartTimeMs(0) , mBinderContextCheckFunc(nullptr) , mBinderContextUserData(nullptr) , mThreadPoolStarted(false) , mThreadPoolSeq(1) , mCallRestriction(CallRestriction::NONE) { // TODO(b/139016109): enforce in build system #if defined(__ANDROID_APEX__) LOG_ALWAYS_FATAL("Cannot use libbinder in APEX (only system.img libbinder) since it is not stable."); #endif //如果binder驱动文件句柄打开正确,则命中if if (mDriverFD >= 0) { // mmap the binder, providing a chunk of virtual address space to receive transactions. //通过mmap进行内存映射,此处可以看到映射的空间大小是为BINDER_VM_SIZE,因为上面open的Binder是调用defaultServiceManager的进程的,所以这里映射的BINDER_VM_SIZE的空间大小也是 //映射的是调用defaultServiceManager的进程的Binder空间,也就是客户端进程 mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str()); close(mDriverFD); mDriverFD = -1; mDriverName.clear(); } } #ifdef __ANDROID__ LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened. Terminating.", driver); #endif } //driver = dev/binder static int open_driver(const char *driver) { //通过open函数,打开dev/binder驱动文件,权限为可读可写,并记录文件句柄,需要注意,此处open出来的binder驱动文件,是属于调用defaultServiceManager的进程的 int fd = open(driver, O_RDWR | O_CLOEXEC); if (fd >= 0) { int vers = 0; //获取Binder Version status_t result = 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(%d) does not match user space protocol(%d)! ioctl() return value: %d", vers, BINDER_CURRENT_PROTOCOL_VERSION, result); close(fd); fd = -1; } 设置binder驱动支持的最大线程数,最大线程数为DEFAULT_MAX_BINDER_THREADS(15) size_t maxThreads = 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 '%s' failed: %s\n", driver, strerror(errno)); } //返回binder驱动文件句柄 return fd; }
- 在创建ProcessState对象时,主要干了下面几件事:
- 通过
open_driver()
打开了一个Binder驱动设备文件,并且设置了该Binder驱动设备支持的最大线程数为15,最后将其返回的文件句柄使用mDriverFD
变量进行了保存。需要特别注意的是:此处打开的Binder驱动设备文件是属于调用defaultServiceManager()
的进程的,也就是相应Client客户端的 - 调用
mmap()
进行了内存映射,映射的空间大小是BINDER_VM_SIZE。同样需要特别注意的是:此处映射的内存是属于调用defaultServiceManager()
的进程的,也就是相应Client客户端的
- 通过
至此
ProcessState::self()
我们就分析完毕了,主要就是进行了ProcessState对象的构建 - 在创建ProcessState对象时,主要干了下面几件事:
2. ProcessState->getContextObject(nullptr)
-
代码路径:android/framework/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) { //通过getStrongProxyForHandle()方法,拿到handle=0的BpBinder对象,而Handle=0代表的就是Service Manager对象 sp<IBinder> context = getStrongProxyForHandle(0); if (context == nullptr) { ALOGW("Not able to get context object on %s.", mDriverName.c_str()); } // The root object is special since we get it directly from the driver, it is never // written by Parcell::writeStrongBinder. internal::Stability::tryMarkCompilationUnit(context.get()); //返回获取到的BpBinder对象 return context; } sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); //先遍历缓存,看是否已经存在handle=0的handle_entry对象 handle_entry* e = lookupHandleLocked(handle); //只有出错时,e才会为空 if (e != nullptr) { // 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. The // attemptIncWeak() is safe because we know the BpBinder destructor will always // call expungeHandle(), which acquires the same lock we are holding now. // We need to do this because there is a race condition between someone // releasing a reference on this BpBinder, and a new reference on its handle // arriving from the driver. //拿到handle所对应的binder对象,当下是第一次创建,其实b=null IBinder* b = e->binder; //因为此时第一次进来,b==null,命中if if (b == nullptr || !e->refs->attemptIncWeak(this)) { //此时handle==0,命中if 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. Parcel data; //此处其实就是在发起一个连接消息,检测驱动是否可用 /* 同样做一下拆分: * 1. IPCThreadState::self() 其实就是返回了一个 IPCThreadState 对象 * 2. IPCThreadState->transact() 其实就是完成和驱动进行通信 * 由此也可以得出,在Binder流程中,真正和驱动进行信息交互的其实是IPCThreadState对象 */ status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, nullptr, 0); //如果返回的是DEAD_OBJECT,那么说明驱动存在问题,直接返回null if (status == DEAD_OBJECT) return nullptr; } //创建一个BpBinder对象,传入的handle=0,所以handle==0的Binder,代表的就是Service Manager b = BpBinder::create(handle); //将这个BpBinder对象,记录到对应的handle_entry的binder变量中 e->binder = b; //BpBinder创建成功的前提下,拿到弱指针,保存在handle_entry的refs变量中 if (b) e->refs = b->getWeakRefs(); //用result记录创建的BpBinder对象 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); } } //返回创建的BpBinder对象 return result; } ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle) { //获取mHandleToObject容器的大小 const size_t N=mHandleToObject.size(); //如果当前容器的大小小于等于传入的handle值,那么就构建一个handle_entry,放入mHandleToObject容器中 if (N <= (size_t)handle) { handle_entry e; e.binder = NULL; e.refs = NULL; status_t err = mHandleToObject.insertAt(e, N, handle+1-N); if (err < NO_ERROR) return NULL; } //返回对应handle值的handle_entry对象,从这个函数可以看出,mHandleToObject是用于保存各个IBinder代理对象的容器,相当于一个缓冲区 return &mHandleToObject.editItemAt(handle); }
- 通过分析,可以看到
ProcessState->getContextObject(NULL)
最终目的就是返回了一个IBinder对象,或者更具体的说,返回的是一个BpBinder对象,拿出新建BpBinder的代码
代码路径:android/framework/native/libs/binder/BpBinder.cpp
BpBinder::BpBinder(int32_t handle, int32_t trackedUid) : mHandle(handle) //保存下handle值,此处是SM的handle=0 , mStability(0) , mAlive(1) , mObitsSent(0) , mObituaries(nullptr) , mTrackedUid(trackedUid) //保存下uid { ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle, this); }
- 在新建BpBinder对象的时候,首先就是将传入的handle值用mHandle变量进行了保存,此处传入的是
handle=0
,也就是设置了SM的BpBinder的mHandle为0。然后调用了IPCThreadState::self()->incWeakHandle(handle);
,接下来看一下这部分的代码
代码路径:android/framework/native/libs/binder/IPCThraedState.cpp
IPCThreadState* IPCThreadState::self() { if (gHaveTLS.load(std::memory_order_acquire)) { restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if (st) return st; //返回了一个IPCThreadState对象 return new IPCThreadState; } // Racey, heuristic test for simultaneous shutdown. if (gShutdown.load(std::memory_order_relaxed)) { ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n"); return nullptr; } pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS.load(std::memory_order_relaxed)) { int key_create_value = pthread_key_create(&gTLS, threadDestructor); if (key_create_value != 0) { pthread_mutex_unlock(&gTLSMutex); ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n", strerror(key_create_value)); return nullptr; } gHaveTLS.store(true, std::memory_order_release); } pthread_mutex_unlock(&gTLSMutex); goto restart; } //IPCThreadState是负责和Binder驱动交互的类 IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), //保存下ProcessState对象 mServingStackPointer(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mStrictModePolicy(0), mLastTransactionBinderFlags(0), mCallRestriction(mProcess->mCallRestriction) { pthread_setspecific(gTLS, this); clearCaller(); //mIn是用来保存 Binder驱动反馈给IPCThreadState的内容 mIn.setDataCapacity(256); //mOut是用来保存 IPCThreadState需要发送给Binder驱动的内容 mOut.setDataCapacity(256); } void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) { LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle); //将handle=0传入发送数据中,并且记录当下需要执行的操作为BC_INCREFS mOut.writeInt32(BC_INCREFS); mOut.writeInt32(handle); // Create a temp reference until the driver has handled this command. proxy->getWeakRefs()->incWeak(mProcess.get()); mPostWriteWeakDerefs.push(proxy->getWeakRefs()); }
- 其实
IPCThreadState::self()
,根据前面分析的ProcessState::self()
是一样的作用,也就是构建对应类的实例,分析代码也确实是这个用处,构建了一个IPCThreadState对象,然后将handle数值以及当前交互指令BC_INCREFS放入存储发送数据的结构体中。
至此,
ProcessState->getContextObject(nullptr)
的代码就分析的差不多了,除了IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, data, NULL, 0);
,transact()
方法在后面的内容中进行分析。总结一下getContextObject()
方法做的工作:- 返回了一个BpBinder对象
- 通过分析,可以看到
3. interface_cast<AidlServiceManager>(new BpBinder(0))
-
此处其实用了模板方法,先把相关代码都拿出来
代码路径:android/framework/native/include/binder/IInterface.h
using AidlServiceManager = android::os::IServiceManager; template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { //此处就转换成IServiceManager::asInterface(obj) return INTERFACE::asInterface(obj); } // ---------------------------------------------------------------------- //DECLARE_META_INTERFACE在IServiceManager.h中定义:DECLARE_META_INTERFACE(ServiceManager); //所以INTERFACE=ServiceManager #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(); \ //IMPLEMENT_META_INTERFACE在IServiceManager.cpp中定义:IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); #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() { } \ #define CHECK_INTERFACE(interface, data, reply) \ if (!data.checkInterface(this)) { return PERMISSION_DENIED; } \ // ---------------------------------------------------------------------- // No user-serviceable parts after this...
-
经过转化:
- obj其实就是BpBinder
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
DECLARE_META_INTERFACE(ServiceManager);
那么最终就可以转化成:
android::sp<IServiceManager> IServiceManager::asInterface( const android::sp<android::IBinder>& obj) { android::sp<IServiceManager> intr; //根据BpBinder,去查找"android.os.IServiceManager"的本地接口,如果找不到,那么就已BpBinder为参数新建BpServiceManager,也就是IServiceManager if (obj != NULL) { intr = static_cast<IServiceManager*>( //因为这个obj是BpBinder对象 obj->queryLocalInterface( IServiceManager::descriptor).get()); if (intr == NULL) { intr = new BpServiceManager(obj); } } return intr; }
- 总结一下,在
asInterface()
中主要就是干两件事- 根据传入的obj调用
queryLocalInterface()
去查找android.os.IServiceManager
- 如果没有找到,那么就调用
BpServiceManager(obj)
进行创建BpServiceManager对象
- 根据传入的obj调用
再逐一展开看一下具体代码,先找到:
queryLocalInterface()
代码路径:android/framework/native/libs/binder/Binder.cpp
sp<IInterface> IBinder::queryLocalInterface(const String16& /*descriptor*/){ //默认直接返回NULL return NULL;}
- 可以看到,IBinder直接返回的就是NULL,那么就会去新建BpServiceManager对象
代码路径:android/framework/native/libs/binder/IServiceManager.cpp
BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl){}
- 继续调用
BpInterface<IServiceManager>(BpBinder(0))
代码路径:android/framework/native/include/binder/IInterface.h
template<typename INTERFACE> inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote) { }
- 继续调用
BpRefBase(BpBinder(0))
代码路径:android/framework/native/libs/binder/Binder.cpp
BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) //mRemote指向 new BpBinder(0),从而 BpServiceManager能够利用 Binder进行通过通信 { extendObjectLifetime(OBJECT_LIFETIME_WEAK); if (mRemote) { mRemote->incStrong(this); // Removed on first IncStrong(). mRefs = mRemote->createWeak(this); // Held for our entire lifetime. } }
- 最后使用mRemote记录下了新建的
BpBinder(0)
对象,至此,defaultServiceManager()
方法就全部分析完了,可以看到,通过defaultServiceManager()
最终就是拿到了一个IServiceManager对象,其实具体来说,应该是一个BpServiceManager对象。
-