binder机制原理分析一共分5个部分,其实省了一点,但是分析到后面都差不多了,以后再补充吧。
1、ServiceManager 进程启动
2、普通Service注册到ServiceManager
3、从ServiceManager中获取服务
4、java层service的注册过程
5、Java层service的获取过程
一般service注册到ServiceManager都经过五个步骤:
- sp proc = (ProcessState::self());获取ProcessState实例;
- sp sm = defaultServiceManager();获取IServiceManager实例;
- XXXService::Instantiate();调试用addService方法,将XXX服务注册到sm中去;
- ProcessState::self()—>startThreadPool();开启binder线程池;
- IPCThreadState::self()—>joinThreadPool();添加到binder线程池;
获取ProcessState实例
涉及到的关键类:
IServiceManager:重写了addServie、gerService、checkService、serviceList四个方法
ProcessState:1、构造中open_driver();mmap();2、getContextObj方法获取ServiceManager类;3、startThreadPool开启线程池new poolThread
IPCThreadState:1、transact方法输入入口;2、writeTransactionDate()方法数据,将数据封装成binder_transact_date并写入到mOut中;3、执行waitForResponse方法等待响应结果。4、joinThreadPool加入到线程池中并开启do while与binder交互;5、执行talkWithDriver方法,将数据封装成binder_write_read通过ioctl的BINDER_WRITE_READ指令发送给binder驱动;6、通过executeCommand方法执行binder响应指令BP_XXX。7、IPCThreadState中还包含mIn、一个mOut,其中mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节
步骤一、ProcessState::self()
获取processState单例
是个单例通过autoLock自锁,返回一个new ProcessState实例对象;ProcessState中定义了binder默认内存大小是1M-8K;默认binder的最大线程数是15。
注意: 这里的binder默认的内存大小和binder的默认最大线程数大小
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
#define DEFAULT_MAX_BINDER_THREADS 15
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
进行processState构造
1、调用open_driver()方法,其实就是调用open()方法获取proc结构体,同时获取binder版本号并设置最大线程数;2、通过mmap()申请虚拟内存空间并进行双映射。
ProcessState::ProcessState()
1、open_driver()中调用open()方法获取proc结构体,同时获取binder版本号和binder最大线程数
mDriverFD(open_driver())
.................{
if (mDriverFD >= 0) {
.................
2、通过mmap机制申请虚拟空间内存并进行双映射
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
}
}
步骤二、获取SM对象defaultServiceManager()
- 通过defaultServiceManager()方法——>调用ProcessState中的getContextObject()方法——>调用getStrongProxyForHandler(0)——>最终获得BpBinder实例。
- 通过interface_cast(new BpBinder(0))模板宏定义替换INTERFACE标签,实现asInterface方法后得到BpServiceManager(new BpBinder(0))。这里的BpServiceManager属于IServiceManager,BpServiceManager继承了BpRefBase,BpRefBase中的成员mRemote指针指向BpBinde(0)。
- IServiceManager实现了IInterface的addService、getService、checkService和serviceList四个方法。所以BpServiceManager也实现了。
先获取BpBinder(0)
sp<IServiceManager> defaultServiceManager(){
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
// 循环获取servicemanager,采用循环应该是考虑到servicemanager进程可能加载慢的问题
while (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){
返回handle = 0即servicemanager代理的强引用
return getStrongProxyForHandle(0);
}
获取handle对应的BpBinder对象。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){
sp<IBinder> result;
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) {
// 查询servicemanager是否可用
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
// 创建handle对应的BpBinder对象,并返回
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;
}
到这里defaultServiceManager先得到的就是interface_cast(new BpBinder(0)),然后继续下一步。
替换模板interface_cast得到BpServiceManager
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
通过宏定义将所有的INTERFACE标签替换成ServiceManager,最终返回new BpServiceManager(obj)对象
#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;
}
再将BpBinder(0)赋给BpRefBase的成员remote对象,通过remote()获取mRemote,就是BpBinder(0)
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
最终:sp defaultServiceManager()最终得到的是new BpServiceManager(new BpBinder(0))
这里BpServiceManager属于IServiceManager,BpBinder属于IBinder。
步骤三、通过Instantiate()注册服务
- Instantiate()这个方法实际上调用的就是defaultServiceManager().addService方法。
class XXXService :public BinderService可以看到XXXService继承BinderService - Instantiate()这个方法在BinderService中实现,可以看到又是个模板类,主要为了将SERVICE标签替换成XXXService去获取serviceName调用publish()方法,因此就是调用BpServiceManager类中的addService方法;
static void instantiate() { publish(); }
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated){
写入通过Parcel对象的data数据包
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
remote()就是BpBinder(0)的引用。这里就是调用的BpBinder的transact方法。
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
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) {
BpBinder又调用了IPCThreadState的transact方法发送数据包
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
线程类IPCThreadState跟每一个binder线程一一对应,每一个binder线程都对应一个IPCThreadState实例(利用TLS:ThreadLocationStorage线程本地存贮实现),IPCThreadState负责最终与binder驱动交互。
核心共两部分:
1、通过writeTransactionData构造结构体;
2、通过talkwithbinder与binder驱动进行交互
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags){
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
<< handle << " / code " << TypeCode(code) << ": "
<< indent << data << dedent << endl;
}
if (err == NO_ERROR) {
1、如果数据没有错,调用writeTransactionData方法:构建binder_transaction_data结构体,封装数据,然后写如mOut中去。
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
2、通过waitForResponse等待binder响应;这里TF_ONE_WAY:0是同步,否正是异步。在waitForResponse方法中通过talkWithdDriver方法不断的跟binder进行io交互,将mOut数据写入binder中,然后将binder中数据读取保存到mIn中。
if ((flags & TF_ONE_WAY) == 0) {
#if 0
if (code == 4) { // relayout
ALOGI(">>>>>> CALLING transaction 4");
} else {
ALOGI(">>>>>> CALLING transaction %d", code);
}
#endif
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
#if 0
if (code == 4) { // relayout
ALOGI("<<<<<< RETURNING transaction 4");
} else {
ALOGI("<<<<<< RETURNING transaction %d", code);
}
#endif
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
<< handle << ": ";
if (reply) alog << indent << *reply << dedent << endl;
else alog << "(none requested)" << endl;
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
writeTransactionData目的是为了封装binder_transaction_data结构体,然后写入到mOut中去
status_t IPCThreadState::writeTransactionData(
int32_t cmd, //此时cmd为BC_TRANSACTION,
uint32_t binderFlags, //binderFlags为0|TF_ACCEPT_FDS
int32_t handle, //handle为0
uint32_t code, //code,注册服务用ADD_SERVICE_TRANSACTION
const Parcel& data, //data包含了要传递给Binder驱动程序的进程间通信数据Parcel包
status_t* statusBuffer ,//statusBuffer为NULL
){
binder_transaction_data tr;
tr.target.handle = handle;//0
tr.code = code;//ADD_SERVICE_TRANSACTION
tr.flags = binderFlags;//0|TF_ACCEPT_FDS
const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize();//数据缓冲区大小
tr.data.ptr.buffer = data.ipcData();//数据缓冲区的起始位置
tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);//偏移数组大小
tr.data.ptr.offsets = data.ipcObjects();//偏移数组起始位置
} else if (statusBuffer) {
........
} else {
........
}
mOut.writeInt32(cmd);//BC_TRANSACTION
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
waitForResponse中while循环开启talkWithBinder不断的跟binder驱动进行交互,最终得到响应的reply
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){
uint32_t cmd;
int32_t err;
while (1) {
// 将写缓冲区mOut中的数据写入驱动
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = (uint32_t)mIn.readInt32();
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
....
// 服务端响应请求
case BR_REPLY:{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
if (err != NO_ERROR) goto finish;
....
}
goto finish;
default:
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
if (err != NO_ERROR) {
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
talkWithDriver通过封装binder_write_read结构体,并调用ioctl命令将数据发送给binder,读也ioctl,写也ioctl;如果mOut不为空,写入数据,如果mIn不为空,读取数据。
status_t IPCThreadState::talkWithDriver(bool doReceive){
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
封装binder的读写数据结构体变量binder_write_read;
binder_write_read bwr;
// 读缓冲区是否为空
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// 当前是否可写入数据到binder驱动
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
// 可读数据
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
// 将bwr的读缓冲指向mIn的数据区
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0; //已写数据
bwr.read_consumed = 0; // 已读数据
status_t err;
do {
#if defined(__ANDROID__)
//与驱动交互,将mOut的数据写入到驱动,读取的数据保存到mIn
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
} while (err == -EINTR);
if (err >= NO_ERROR) {
// 将已写入驱动的数据从mOut中移除
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
}
// 将读取到的数据信息保存到mIn
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
return NO_ERROR;
}
return err;
}
开启binder线程池:startThreadPool()
调用startThreadPool(),最终new PoolThread方法创建并开启线程池
void ProcessState::startThreadPool(){
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
添加到binder线程池:joinThreadPool()
通过IPCThreadState中的joinThreadPool()方法执行线程looper。
void IPCThreadState::joinThreadPool(bool isMain){
LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
1、设置线程状态
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
// 设置当前线程的调度策略
set_sched_policy(mMyThreadId, SP_FOREGROUND);
status_t result;
do {
processPendingDerefs();
2、不断执行从binder驱动获取到的命令
result = getAndExecuteCommand();
....
// 非主线程超时,直接退出
if(result == TIMED_OUT && !isMain) {
break;
}
} while (result != -ECONNREFUSED && result != -EBADF);
// 退出线程池
mOut.writeInt32(BC_EXIT_LOOPER);
//停止与binder的通信
talkWithDriver(false);
}
status_t IPCThreadState::getAndExecuteCommand(){
status_t result;
int32_t cmd;
// 与binder进行数据通信
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) return result;
cmd = mIn.readInt32();
// 进程中正在执行任务的线程数加一
pthread_mutex_lock(&mProcess->mThreadCountLock);
mProcess->mExecutingThreadsCount++;
if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
mProcess->mStarvationStartTimeMs == 0) {
mProcess->mStarvationStartTimeMs = uptimeMillis();
}
pthread_mutex_unlock(&mProcess->mThreadCountLock);
result = executeCommand(cmd);
....
// 保持线程处于Forground状态
set_sched_policy(mMyThreadId, SP_FOREGROUND);
}
return result;
}
总结:
主要分为5步骤:
-
通过ProcessState::self()获取processState实例:实例构造的时候通过open_driver()方法打开驱动设备文件,获取binder版本号,设置binder最大线程,通过mmap机制申请内存并实现双映射;
-
通过defaltServiceManager()获取servicemager实例:方法中调用了interface_cast (ProcessState::self()—>getContextObj())方法获取serviceManager实例。
-
通过instantiate将服务add到serviceManager中去:
-
通过startThreadPool开启线程池:
-
通过joinThreadPool添加到线程池: