基于Binder的IPC通讯机制
来源:互联网 发布:超值的网络推广多少钱 编辑:程序博客网 时间:2024/05/23 14:33
Android版本:4.4
模块:基于Binder的线程间IPC通讯机制
初识Android系统,在此做个足迹,文章中有很多解释错误的地方,希望得到大家的鼓励跟指正
简介:
binder 是linux提供的一套轻量级的IPC组件框架,Android系统可以被看作是一套C/S架构,而系统的各个功能都通过IPC通讯机制
结合在一起,android 启动的时候会注册各种服务到ServiceManager中,在应用层的角度来看可以当作是Client客户端,通过发送请求读取binder设备节点(dev/binder),由binder驱动发送指令到内核空间(通俗的理解就是一块内存)与Service端进行沟通的到相对应的数据返回给Client,Service端调用驱动层得到硬件相关数据给Client,ServiceManager的功能是管理各种系统服务,并且Client要访问某个Service需要通过ServiceManager得到相关Service的状态然后由它提供Service,binder在Android系统中可以看作是Client与Service间通讯的提供者,但是Android系统并不仅仅只有这一种通讯方式,还有基于Socket/Pipe的通讯,它相对于其它的通讯方式有点在于:使用内存共享,提供有线程池,支持面向对象
以多媒体系统来了解一下IPC通讯机制
多媒体系统启动入口:framework/av/media/mediaserver/main_mediaserver.cpp
这个文件中有一个main入口函数,在这个函数中主要实现的功能是初始化多媒体系统相关服务跟类
/*获得一个ProcessState实例,
*每个进程只有一个ProcessState
* */
sp<ProcessState> proc(ProcessState::self());
/*得到一个IserverManager 用来注册并管理所有的Service*/
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
/*初始化系统音频服务*/
AudioFlinger::instantiate();
/*多媒体服务*/
MediaPlayerService::instantiate();
/*相机服务*/
CameraService::instantiate();
/*音频系统服务*/
AudioPolicyService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
入口函数中第一步便创建了一个进程,其功能主要在类framework/native/libs/binder/ProcessState.cpp中实现
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
/*gProcess是State.cpp中的一个全局变量
*默认为空,不为空表示已经创建过
*单例模式
* */
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
在其构造函数中打开了binder虚拟设备
ProcessState::ProcessState()
/*打开binder这个虚拟设备*/
: mDriverFD(open_driver())
, mVMStart(MAP_FAILED)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// XXX Ideally, there should be a specific define for whether we
// have mmap (or whether we could possibly have the kernel module
// availabla).
#if !defined(HAVE_WIN32_IPC)
// 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;
}
#else
mDriverFD = -1;
#endif
}
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
打开binder设备函数
static int open_driver()
{
/*打开/dev/binder设备*/
int fd = open("/dev/binder", O_RDWR);
if (fd >= 0) {
fcntl(fd, F_SETFD, FD_CLOEXEC);
int vers;
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 does not match user space protocol!");
close(fd);
fd = -1;
}
/*通过ioctl告诉binder驱动。这个fd(binder)最大支持15个线程*/
size_t maxThreads = 15;
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;
}
ProcessState创建过程暂时到这里,重要的一点是binder虚拟设备是在其构造函数中打开并初始化的,再回头看看mian_mediaserver.cpp中的入口函数,完成了ProcessState的创建之后紧接着创建了IServiceManager这个重要的类:sp<IServiceManager> sm = defaultServiceManager(); (framework//native/libs/binder/IServiceManager.cpp)
sp<IServiceManager> defaultServiceManager()
{
/*使用了单例模式*/
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
/*interface_cast 该函数在IInteface.h中实现*/
gDefaultServiceManager = interface_cast<IServiceManager>(
/*调用了ProcessState的getContextObject函数*/
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
ProcessState::self()->getContextObject(NULL))调用了ProcessState的getContextObject()函数
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
return getStrongProxyForHandle(0);
}
getStrongProxyForHandle函数原型,在ProcessState.cpp中
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
/*
*根据索引查找对应的资源
*如果函数lookupHandleLocked查找不到对应的资源
*就会创建一个需要填充的空项
* */
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) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
/*创建一个Bpinder*/
b = new BpBinder(handle);
e->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);
}
}
return result;
}
上面的函数返回了一个BpBinder,跟它很像的还有BBInder,IBinder Ibinder 提供了一些操作Binder虚拟设备的函数,但是具体的操作不是由它实现,BpBinder跟BBinder 都继承于IBinder,这三个类可以看作一个小单元的C/S架构,BpBinder 是整个IPC架构中的客户端跟服务端沟通的代理类,它可以看作是这三者中的客户端,而BBinder是IPC架构中的客户端跟服务端沟通的目的端,负责接收RPC代码和数据,并在Binder Driver内部生成Binder节点,它可以看作是三者中的服务端,这里创建返回的是BpBinder目的就是:在各种系统服务的角度来看 ,我们需要向ServiceManager中注册,并给出相关的数据,相对于ServiceManager而言 系统的各种服务属于客户端,作为与客户端交互的代理类BpBinder在这里得到使得ServiceManager跟各种系统服务的交互关系更加明确,这里的IPC架构中的客户端理解为应用层的各种请求,BpBinder 跟BBinder是一一对应的,他们之间通过handler来标识
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))这是获取IserviceManager的函数
通过interface_cast函数传入 BpBinder 得到 IserviceManager,下面是interface_cast函数(位于framework//native/include/binder/IInterface.h)
/*模板函数
*C++简化函数重载的一种手段
*我们只需要定义一个,调用端通过参数类型来实现
*不同的功能
*/
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
/*等价于IServiceManager::asInterface(obj)*/
return INTERFACE::asInterface(obj);
}
上面的函数意思说调用IserviceManager类中的asInterface函数传入BpBinder得到IServiceManager??在IServiceManager中找了找没找到
原来Android 通过DECLARE_INTERFACE宏跟IMPLEMENT_INTERFACE宏将BpBinder作为参数传入了BpServiceManager中创建了一个于跨进程通讯的业务类
DECLARE_INTERFACE宏跟IMPLEMENT宏都在IInterface.cpp文件中声明,如下
/*声明函数的宏(类似java的interface接口)*/
#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() { } \
#define CHECK_INTERFACE(interface, data, reply) \
if (!data.checkInterface(this)) { return PERMISSION_DENIED; } \
在IServiceManager的头文件中可以看到有对DECLARE_META_INTERFACE宏的引用(framework/native/include/binder/IServiceManager.h)
class IServiceManager : public IInterface
{
public:
/*很重要的一个宏引用*/
DECLARE_META_INTERFACE(ServiceManager);
.........
};
在IServiceManager.cpp文件中将使用IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");将IInterface.h 文件中的IMPLEMENT_META_INTERFACE宏各个参数替换为在IServiceManager.cpp中传入的参数,即IServiceManager.cpp文件中包含了asInterface函数
上面在interface_cast函数中看到了这样的引用:
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
/*等价于IServiceManager::asInterface(obj)*/
return INTERFACE::asInterface(obj);
}
asInterface函数在IMPLEMENT_META_INTERFACE中声明,它是android 如何将BpBinder跟IServiceManger挂钩的关键函数,想要走通基于Binder的IPC通讯机制 研究这个函数必然的。如下:
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; \
}
将参数还原后如下:
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; \
}
总的看来main_mediaservice.cpp中入口函数里面的getDefaultServiceManager得到的其实就是BpServiceManager,它其实就是将BpBinder作为一个参数创建了一个BpServiceManager对象
到这里又出现了三胞胎:IServiceManager/BpServiceManager/BnServiceManager,BnServiceManager 同时派生于IServerManager/Binder BpServiceManager虽然从BpInterface中派生,但是这条分支貌似跟Binder相关的联系,BnServiceManager 是一个虚类,没有方法体的具体实现,需要其子类来实现相关函数的功能
既然getDEfaultServiceManager()函数几番周折,如此麻烦的得到以BpBinder做参数创建的BpServiceManager对象,那这个类是不是很有可能跟Binder通讯有关,下面看看BpServiceManager是什么个东东
BpServiceManager 是IServiceManager.cpp中的一个内部类如下:
class BpServiceManager : public BpInterface<IServiceManager>
{
/*构造函数*/
public:
BpServiceManager(const sp<IBinder>& impl)
/*调用基类BpInterface的构造函*/
: BpInterface<IServiceManager>(impl)
{
}
/*虛函数*/
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
for (n = 0; n < 5; n++){
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
ALOGI("Waiting for service %s...\n", String8(name).string());
sleep(1);
}
return NULL;
}
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
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);
/*remote返回的是BpBinder对象*/
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
virtual Vector<String16> listServices()
{
Vector<String16> res;
int n = 0;
for (;;) {
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeInt32(n++);
status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
if (err != NO_ERROR)
break;
res.add(reply.readString16());
}
return res;
}
};
在内部类BpServiceManager的构造函数中调用了基类的构造函数BpInterface,下面看看基类的构造函数是如何实现的,BpInterface类在IInterface.h文件中声明,如下
继承自INTERFACE跟BpRefBase
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
};
上面BpServiceManager的构造函数中调用了IInterface中的模板函数,如下
inline关键字声明的函数表示编译的时候直接将下面的代码插入到对应的调用处,提高代码的执行效率
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
/*继承自BpRefBase*/
: BpRefBase(remote)
{
}
BpRefBase类为Binder.cpp中的一个内部类:(Binder.cpp位于frame/native/libs/binder/Binder.cpp),在Binder.h文件中声明
BpRefBase::BpRefBase(const sp<IBinder>& o)
/*初始化Binder中的一些变量
最开始创建的一个BpBinder现在的指针给了Ibinder
*/
: 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.
}
}
Binder.h头文件中的声明
class BpRefBase : public virtual RefBase
{
protected:
BpRefBase(const sp<IBinder>& o);
virtual ~BpRefBase();
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
inline IBinder* remote() { return mRemote; }
inline IBinder* remote() const { return mRemote; }
private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;
RefBase::weakref_type* mRefs;
volatile int32_t mState;
};
总结下:上面mian_mediaservice.cpp函数中的初始化工作 一开始通过ProcesState创建了一个进程,并且打开了binder虚拟设备,第二步在getDefaultServiceManager中将BpBinder创建并作为一个参数创建了BpServiceManager,然后在这里将创建的BpBinder赋值给了IBinder
再回头看看main_mediaservice.cpp中的函数--->MediaPlayerService::instantiate();该类位于framework/av/media/libmediaplayerservice/MediaPlayerService.cpp
下面是instantiate()函数:
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
仅仅是实例化了MediaPlayerService对象并将自己添加到BpServiceManager中,addService函数在IServiceManager中
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);
/*remote返回的是BpBinder对象*/
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
如何跟Binder通讯主要就看BpBinder的transact函数,BpBinder.cpp函数位于(framework/native/libs/binder/BpBinder.cpp),下面是transact函数:
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
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函数,先看看IPCThreadState::self() IPCThreadState.cpp位于framework/native/libs/binder/IPCThreadState.cpp
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {
restart:
/*TLS是Thread Local Storage的简称,每个线程都有,但是不对其它线程公开,可以通过pthread_getspecific获取内存空间里面的内容,与之对应的函数是pthread_getspecific,下面的代码是从当前线程内存空间中得到保存的IPCThreadState对象,如果为空就创建一个
*/
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()
: mProcess(ProcessState::self()),
mMyThreadId(androidGetTid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
//将自己存储在TLS中
pthread_setspecific(gTLS, this);
clearCaller();
//两个Parcle数据存储类,一个是接收客户端发过来的数据,一个是向binder发送数据的
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
下面看看IPCThreadState的transact函数到底是怎样跟binder沟通的,该函数中有俩Parcle ,一个是客户端的请求数据 一个是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);
}
if (err == NO_ERROR) {
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
//向binder发送消息
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 (code == 4) { // relayout
} else {
}
//等待binder返回消息
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
...............
return err;
}
下面看看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是跟Binder设备通讯的数据结构
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中
mOut.writeInt32(cmd);
//把数据写入mOut中
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
上面看到仅仅是写到了Parcle中,在transact函数中 执行writeTransactionData函数之后会执行waitForResponse函数,获得返回结果,下面是waitForResponse函数原型
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
//跟binder驱动交互,并得到交互状态,并且将返回的数据封装到mIn中
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;
}
//下面是根据cmd指令做相对应的处理
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:
//跟据cmd指令处理完成后即执行指令
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;
}
跟驱动交互的函数原型如下:
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
//跟binder沟通的数据结构
binder_write_read bwr;
// 判断是否有数据可读
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// 如果正在从缓冲区读取数据,那么继续读数据
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (long unsigned int)mOut.data();
// 将通讯返回的数据mIn中的数据填充到bwr里
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (long unsigned int)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
if (outAvail != 0) {
alog << "Sending commands to driver: " << indent;
const void* cmds = (const void*)bwr.write_buffer;
const void* end = ((const uint8_t*)cmds)+bwr.write_size;
alog << HexDump(cmds, bwr.write_size) << endl;
while (cmds < end) cmds = printCommand(alog, cmds);
alog << dedent;
}
alog << "Size of receive buffer: " << bwr.read_size
<< ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
}
// 如果没有数据就返回出去
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_LOG_COMMANDS() {
alog << "About to read/write, write size = " << mOut.dataSize() << endl;
}
#if defined(HAVE_ANDROID_OS)
//ioctl函数控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
IF_LOG_COMMANDS() {
alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
}
} while (err == -EINTR);
IF_LOG_COMMANDS() {
alog << "Our err: " << (void*)err << ", write consumed: "
<< bwr.write_consumed << " (of " << mOut.dataSize()
<< "), read consumed: " << bwr.read_consumed << endl;
}
//binder_write_read 是封装的跟binder通讯的数据结构体
if (err >= NO_ERROR) {
//需要发送的数据不为空则表明需要继续发送数据
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < (ssize_t)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);
}
IF_LOG_COMMANDS() {
TextOutput::Bundle _b(alog);
alog << "Remaining data size: " << mOut.dataSize() << endl;
alog << "Received commands from driver: " << indent;
const void* cmds = mIn.data();
const void* end = mIn.data() + mIn.dataSize();
alog << HexDump(cmds, mIn.dataSize()) << endl;
while (cmds < end) cmds = printReturnCommand(alog, cmds);
alog << dedent;
}
return NO_ERROR;
}
return err;
}
现在添加MediaPlayerService 的功能到这里结束,返回的数据已经封装到mIn(Parcle)中
0 0
- 基于Binder的IPC通讯机制
- Android的IPC机制-Binder
- android的IPC机制 - Binder
- Android的IPC机制Binder
- Android的IPC机制-Binder
- Android的IPC机制Binder
- 深入理解 Android 的 IPC 机制--------Binder
- Binder---- Android 的IPC 通信机制
- Binder---- Android 的IPC 通信机制
- Binder---- Android 的IPC 通信机制
- Binder---- Android 的IPC 通信机制
- 技术内幕:Android的IPC机制-Binder
- Binder---- Android 的IPC 通信机制
- 深入理解 Android 的 IPC 机制--------Binder
- Android的IPC机制——Binder
- Binder IPC 机制
- IPC 机制Binder 剖析
- IPC binder 机制历史
- java工程路径
- java服务器个人经验
- 平台即服务(Paas)
- PHP 时间的获取和使用 date()和strtotime()函数
- java个人经验
- 基于Binder的IPC通讯机制
- SOAP协议简介
- php-MySQL笔记集合
- Spring MVC : Java模板引擎 Thymeleaf (二)
- 安装zabbix客户端脚本
- 手机DCIM\.thumbnails 文件删除
- Excel部分快捷键用法(2)
- Java学习课程(1)
- phonegap运行原理