目录
1. 前言
本文主要是binder系列文章的总结笔记,主要是理清binder的总体流程和总体架构,期间会对照Android R进行代码重读,也会按照自己的理解对内容进行调整,以加深对binder总体的理解。本文主要讲述 获取ServiceManager。
2. 主要类与对象
IInterface:
IServiceManager:
ProcessState:ProcessState是负责打开Binder节点并做mmap映射
IPCThreadState:IPCThreadState是负责与Binder驱动进行具体的命令交互。在android binder设计中,IPCThreadState是一个binder线程的一个抽象,用于管理binder线程的具体执行。这个类被设计为,其对象在每个binder线程中唯一。为了控制这个类的对象的创建,其构造函数也被声明为private,并且只能通过IPCThreadState::self()来创建或访问IPCThreadState类的对象
Bpbinder: 新创建的BpBinder, 会被赋值给binder_entry的binder变量,而binder_entry位于ProcessState类的IPCThreadState友元类中,也就是client端的进程中,IPCThreadState维护者一个binder_entry向量数组,可以保存多个服务的Bpbinder
下面我们主要以vold守护进程这个服务获取serviceManager服务为例说明defaultServiceManager的处理过程
3. vold/main
vold/main
|--mkdir("/dev/block/vold", 0755);
|--vm = VolumeManager::Instance()
|--nm = NetlinkManager::Instance()
|--vm->start()
|--process_config(vm, &has_adoptable, &has_quota, &has_reserved)
|--android::vold::VoldNativeService::start()
| |--IPCThreadState::self()->disableBackgroundScheduling(true);
| |--BinderService<VoldNativeService>::publish();
| |--sp<ProcessState> ps(ProcessState::self())
| |--ps->startThreadPool()
| |--ps->giveThreadPoolName()
|--nm->start()
|--coldboot("/sys/block");
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
4. defaultServiceManager
sp<IServiceManager> defaultServiceManager()
|--sp<AidlServiceManager> sm = nullptr;
|--sm = interface_cast<AidlServiceManager>
| (ProcessState::self()->getContextObject(nullptr));
| |--ProcessState::self()
| |--sp<IBinder> ProcessState::getContextObject(const sp<IBinder>&)
|--gDefaultServiceManager = new ServiceManagerShim(sm)
|--const sp<AidlServiceManager>& impl
|--mTheRealServiceManager(impl)
gDefaultServiceManager的创建过程,可分解为以下3个步骤:
-
ProcessState::self():用于获取ProcessState对象(也是单例模式),每个进程有且只有一个ProcessState对象,存在则直接返回,不存在则创建
-
getContextObject(): 用于获取BpBinder对象,对于handle=0的BpBinder对象,存在则直接返回,不存在才创建
-
interface_cast():用于获取BpServiceManager对象
sp<IServiceManager> defaultServiceManager()
{
std::call_once(gSmOnce, []() {
//AidlServiceManager
sp<AidlServiceManager> sm = nullptr;
while (sm == nullptr) {
sm = interface_cast<AidlServiceManager>
(ProcessState::self()->getContextObject(nullptr));
if (sm == nullptr) {
ALOGE("Waiting 1s on context object on %s.",
ProcessState::self()->getDriverName().c_str());
sleep(1);
}
}
gDefaultServiceManager = new ServiceManagerShim(sm);
});
return gDefaultServiceManager;
}
std::call_once 这个是c++11上的一个新特性,用于需要保证某个流程在多线程场景中也只执行一次,需要和std::once_flag配套使用,用来区分不同的流程。
defaultServiceManager被客户端调用时,最主要的就是要拿到service manager的Bpbinder。
|- - ProcessState::self
ProcessState::self()
|--if (gProcess != nullptr) return gProcess;
|--gProcess = new ProcessState(kDefaultDriver)
|--open_driver(driver)
| |--status_t result = ioctl(fd, BINDER_VERSION, &vers)
| |--size_t maxThreads = DEFAULT_MAX_BINDER_THREADS
| |--result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
|--mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE |
MAP_NORESERVE, mDriverFD, 0);
ProcessState的单例模式的惟一性,因此一个进程只打开binder设备一次,其中ProcessState的成员变量mDriverFD记录binder驱动的fd,用于访问binder设备。ProcessState是负责打开Binder节点并做mmap映射,IPCThreadState是负责与Binder驱动进行具体的命令交互。
open_driver()
会打开binder设备,open()方法经过系统调用,进入Binder驱动,然后调用方法binder_open(),该方法会在Binder驱动层创建一个binder_proc对象,此binder_proc对象是vold进程的,再将binder_proc对象赋值给fd->private_data,同时放入全局链表binder_procs
注:servicemanager作为第一个binder_proc被链入binder_procs,详见Android binder学习笔记1 - 启动ServiceManager
mmap
创建ProcessState对象时会执行mmap,调用mmap()进行内存映射,对应于Binder驱动层的binder_mmap()方法,该方法会在Binder驱动层创建Binder_buffer对象,并放入当前binder_proc的proc->buffers链表。
|- -ProcessState::getContextObject
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>&)
| //获取handle=0的IBinder
|--sp<IBinder> context = getStrongProxyForHandle(0);
| | //本地查找handle为0的handle_entry,刚开始肯定没有
| | //因此handler_entry->binder是nullptr
| |--handle_entry* e = lookupHandleLocked(0)
| |--IBinder* b = e->binder
| |--if (b == nullptr || !e->refs->attemptIncWeak(this))
| | if (handle == 0)
| | //通过ping操作测试binder是否准备就绪
| | status_t status = IPCThreadState::self()->transact(
| | 0, IBinder::PING_TRANSACTION, data, nullptr, 0);
| | //当handle值所对应的IBinder不存在或弱引用无效时,则创建BpBinder对象
| | b = BpBinder::create(handle);
| | |--new BpBinder(handle, trackedUid)
| | | //将handle相对应Binder的弱引用增加1
| | |--IPCThreadState::self()->incWeakHandle(handle, this)
| | e->binder = b;
|--internal::Stability::tryMarkCompilationUnit(context.get());
|--return context
getContextObject()用于获取BpBinder对象,对于handle=0的BpBinder对象,存在则直接返回,不存在才创建
- lookupHandleLocked:根据handle值来查找对应的handle_entry, handle_entry是一个结构体,里面记录IBinder和weakref_type两个指针。当handle大于mHandleToObject的Vector长度时,则向该Vector中添加(handle+1-N)个handle_entry结构体,然后再返回handle对应位置的handle_entry结构体指针
当handle值所对应的IBinder不存在或弱引用无效时会创建BpBinder,否则直接获取:
-
IPCThreadState::self()->transact:针对handle==0的特殊情况,通过PING_TRANSACTION来判断是否准备就绪。
-
BpBinder::create: 创建BpBinder对象,其中会将handle相对应Binder的弱引用增加1. 新创建的BpBinder, 会被赋值给binder_entry的binder变量,而binder_entry位于ProcessState类,也就是client端的进程中
-
如果在context manager还未生效前,一个BpBinder的本地引用就已经被创建,那么驱动将无法提供context manager的引用。
-
返回创建的Bpbinder
|- - -lookupHandleLocked
lookupHandleLocked(handle)
|--const size_t N=mHandleToObject.size();
| //当handle大于mHandleToObject的长度时,创建handle_entry
|--if (N <= (size_t)handle)
| handle_entry e;
| e.binder = nullptr;
| e.refs = nullptr;
| //从mHandleToObject的第N个位置开始,插入(handle+1-N)个e到队列中
| status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
|--return &mHandleToObject.editItemAt(handle)
lookupHandleLocked:根据handle值来查找对应的handle_entry, handle_entry是一个结构体,里面记录IBinder和weakref_type两个指针。当handle大于mHandleToObject的Vector长度时,则向该Vector中添加(handle+1-N)个handle_entry结构体,然后再返回handle对应位置的handle_entry结构体指针
struct handle_entry {
IBinder* binder;
RefBase::weakref_type* refs;
};
|- - -IPCThreadState::self()->transact
当查找到handle_entry为空,且当handle为0,则说明是servicemanager还没有创建binder实体,通过ping操作测试binder是否准备就绪
IPCThreadState* IPCThreadState::self()
|--if (gHaveTLS.load(std::memory_order_acquire)) {
| //当执行完第一次之后,再次运行的时候就已经有IPCThreadState实例,只需要获取就可以使用
| const pthread_key_t k = gTLS;
| IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
| if (st) return st;
| return new IPCThreadState;
| }
|--pthread_mutex_lock(&gTLSMutex);
| //初始的gHaveTLS的值false,所以第一次调用的时候,会执行这里的代码
| 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设置为true
| gHaveTLS.store(true, std::memory_order_release);
| }
| pthread_mutex_unlock(&gTLSMutex);
IPCThreadState负责与binder进行命令交互,通过IPCThreadState::self来获取IPCThreadState单例,如果存在则返回,否则创建
|- -interface_cast
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
这是一个模板函数,可得出,interface_cast() 等价于 AidlServiceManager::asInterface()。
using AidlServiceManager = android::os::IServiceManager;
而AidlServiceManager就是IServiceManager,因此interface_cast转换为如下:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
接下来,再来说说asInterface()函数的具体功能。根据frameworks/native/libs/binder/include/binder/IInterface.h文件中IMPLEMENT_META_INTERFACE(INTERFACE, NAME) 的宏定义,对于asInterface()函数,最终转换为:
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
{
android::sp<IServiceManager> intr;
if(obj != NULL) {
intr = static_cast<IServiceManager *>(
obj->queryLocalInterface(IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
对于最新版本的Android R是否不会创建BpServiceManager,而是创建了ServiceManagerShim
|- -ServiceManagerShim(sm)
gDefaultServiceManager = new ServiceManagerShim(sm)
|--const sp<AidlServiceManager>& impl
|--mTheRealServiceManager(impl)
创建ServiceManagerShim,ServiceManagerShim实际就是之前版本的BpServiceManager,sm为
参考文档
Binder系列4—获取ServiceManager
Binder进程与线程ProcessState以及IPCThreadState