下面将通过一个系列来对binder进行解析,虽然之前很多人都已经写过相关的博客,不过还是决定自己来写写,把整个思路理一理,增加自己对binder的认识,也同时希望对大家有所帮助。
首先我们来看的就是ServiceManager注册服务的过程,通过MediaPlayerService的注册过程来讲解整个注册的流程,主要为了看看binder跨进程通信的具体过程。
下面直接上源码。
/frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc, char** argv)
{
// 1、得到一个ProcessState实例
sp<ProcessState> proc(ProcessState::self());
// 2、获取BpServiceManager对象
sp<IServiceManager> sm = defaultServiceManager();
// 3、注册多媒体服务
MediaPlayerService::instantiate();
// 4、启动Binder线程池
ProcessState::self()->startThreadPool();
// 5、当前线程加入到线程池
IPCThreadState::self()->joinThreadPool();
}
一、得到一个ProcessState实例
framework/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
//实例化ProcessState
gProcess = new ProcessState;
return gProcess;
}
使用单例模式,保证每一个进程只有一个ProcessState对象
下面看看ProcessState的创建
ProcessState::ProcessState()
: mDriverFD(open_driver()) // 打开Binder驱动
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
//采用内存映射函数mmap,给binder分配一块虚拟地址空间
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
close(mDriverFD);
mDriverFD = -1;
}
}
}
下面看看驱动的打开过程
static int open_driver()
{
// 打开/dev/binder设备,建立与内核的Binder驱动的交互通道
int fd = open("/dev/binder", O_RDWR);
if (fd >= 0) {
fcntl(fd, F_SETFD, FD_CLOEXEC);
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1) {
close(fd);
fd = -1;
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
close(fd);
fd = -1;
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
// 通过ioctl设置binder驱动
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));
}
return fd;
}
二、获取BpServiceManager对象
/frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
// 同样使用的是单例模式
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
// 进入BpServiceManager的创建
// 分为两步:
// 1、BpBInder binder = ProcessState::self()->getContextObject(NULL)
// 2、interface_cast<IServiceManager>(binder)
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
1、ProcessState::self()->getContextObject(NULL)
/frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
// 同样使用的是单例模式
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
return getStrongProxyForHandle(0);
}
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) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
// 如果 e->binder为null,就需要创建一个新的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;
}
可以看到最终返回的其实就是new BpBinder(0);
2、interface_cast<IServiceManager>
(new BpBinder(0))
interface_cast方法是一个模板方法,定义在IInterface.h文件中
/frameworks/native/include/binder/IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
所以,interface_cast<IServiceManager>
(new BpBinder(0))等价于:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
可以看到实质就是调用了IServiceManager的asInterface方法,即:
IServiceManager::asInterface(new BpBinder(0));
下面在IServiceManager.h看看这个方法的定义
/frameworks/native/libs/binder/IServiceManager.h
class IServiceManager : public IInterface
{
public:
// 这个模板方法实质就是IServiceManager::asInterface(obj)
DECLARE_META_INTERFACE(ServiceManager);
// ......
}
下面我们来看看这个模板方法的定义
/frameworks/native/include/binder/IInterface.h
#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(); \
-------------------------------------------------------------------------
下面是该方法的实现模板
#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() { }
下面进行替换可以得到定义为:
static const android::String16 descriptor; \
static android::sp<IServiceManager> asInterface( \
const android::sp<android::IBinder>& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
IServiceManager(); \
virtual ~IServiceManager(); \
-------------------------------------------------------------------------
IServiceManager::asInterface(obj)的实现为:
const android::String16 IServiceManager::descriptor(NAME); \
const android::String16& \
IServiceManager::getInterfaceDescriptor() const { \
return IServiceManager::descriptor; \
} \
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; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { }
从上面可以看到实质是new BpServiceManager(obj)创建了一个BpServiceManager对象。
从上面分析可以知道:
interface_cast<IServiceManager>
(binder)实质等价为:
new BpServiceManager(new BpBinder(0))
也就是说 defaultServiceManager()方法最终返回的对象为BpServiceManager对象。
下面看看IServiceManager.cpp中BpServiceManager类的构造方法
/frameworks/native/libs/binder/IServiceManager.cpp
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
BpServiceManager(const sp<IBinder>& impl)
: BpInterface<IServiceManager>(impl)
{
}
//......
}
可以看到BpServiceManager继承了BpInterface方法,并且同时在构造函数中也调用了BpInterface的构造方法。
BpServiceManager(new BpBinder(0))->BpInterface<IServiceManager>
(new BpBinder(0))
下面看看BpInterface的构造函数
/frameworks/native/include/binder/IInterface.h
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
-------------------------------------------------------------------------
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}
它是一个模板方法,替换之后为:
class BpInterface : public IServiceManager, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
----------------------------------------------------------------------------
inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}
可以看到BpInterface继承了IServiceManager和BpRefBase,并且调用了BpRefBase的构造方法
BpServiceManager(new BpBinder(0))->BpInterface<IServiceManager>
(new BpBinder(0))–>BpRefBase(new BpBinder(0))
下面看看BpRefBase的构造方法
/frameworks/native/libs/binder/Binder.cpp
BpRefBase::BpRefBase(const sp<IBinder>& o)
// 这里实质就是将new BpBinder(0)这个对象复制给mRemote
// 即mRemote持有对BpBinder对象的引用
: mRemote(o.get()), mRefs(NULL), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
}
上面类直接的关系图如下所示:
三、注册多媒体服务
当我们拿到这个BpServiceManager对象之后,相当于我们就拿到了ServiceManager的远程代理对象,使用BpServiceManager这个代理对象我们就可以实现对ServiceManager的远程调用,下面我们通过注册多媒体服务来看看它的调用流程。
/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());
}
上面已经说过defaultServiceManager()是一个单例方法,返回的是BpServiceManager对象,下面看看该对象的addService方法,它实现的是对远程ServiceManager对象的addService方法的调用。
/frameworks/native/libs/binder/IServiceManager.cpp
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
remote()方法返回的就是前面设传递进去的BpBinder对象,也就是说最终会将调用的数据进行打包到Parcel对象中,然后调用BpBinder对象的transact方法。
/frameworks/native/libs/binder/BpBinder.cpp
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;
}
可以看到最终调用的是IPCThreadState对象的transact方法。
上面的调用关系图如下:
下面我们来看看具体的调用过程。
/frameworks/native/libs/binder/IPCThreadState.cpp
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {
restart:
const pthread_key_t k = gTLS;
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
return new IPCThreadState;
}
if (gShutdown) return NULL;
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {
if (pthread_key_create(&gTLS, threadDestructor) != 0) {
pthread_mutex_unlock(&gTLSMutex);
return NULL;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
实质就是获取一个IPCThreadState对象,这是一个线程相关的对象,每个线程只有一个IPCThreadState对象,下面看看IPCThreadState的构造方法
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mMyThreadId(androidGetTid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
pthread_setspecific(gTLS, this);
clearCaller();
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
每个IPCThreadState对象都有一个mIn和一个mOut,其中mIn接收来自Binder设备的数据,mOut存放发往Binder设备的数据。
另外,我们可以看到在IPCThreadState中有一个mProcess变量它对应的就是ProcessState的引用,我们知道,在ProcessState中我们在前面打开过binder驱动。
下面我们来具体看看IPCThreadState对象的transact方法。
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) {
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);
}
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;
}
上面过程主要有两步:
1、writeTransactionData方法进行数据写入
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
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) {
tr.flags |= TF_STATUS_CODE;
*statusBuffer = err;
tr.data_size = sizeof(status_t);
tr.data.ptr.buffer = statusBuffer;
tr.offsets_size = 0;
tr.data.ptr.offsets = NULL;
} else {
return (mLastError = err);
}
mOut.writeInt32(cmd); //cmd = BC_TRANSACTION
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
上面的过程就是将addService的请求信息写入到mOut中。
2、waitForResponse方法进行请求发送并等待回复
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT:
{
ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
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;
if (reply) {
if ((tr.flags & TF_STATUS_CODE) == 0) {
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t),
freeBuffer, this);
} else {
err = *static_cast<const status_t*>(tr.data.ptr.buffer);
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t), this);
}
} else {
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t), this);
continue;
}
}
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中,把mOut发出去,然后从driver中读到回复数据放到mIn中了。这样就完成了一次跨进程的操作。
前面我们说到,我们把mOut发出去,那边另一端肯定会取出这个数据,然后根据这个数据的需要完成知道的操作,完成之后把需要返回的数据再写入到driver中,这样我们这端就可以从driver中读到回复数据放到mIn中,完成一次跨进程的操作,我们前面所分析的整个过程是客户端发起的过程,那么另一端就是服务端,我们下面就要分析服务端是怎么从driver获取到mOut数据,执行相应的操作,然后把返回数据再写回到driver,让客户端来获取。