码迷,mamicode.com
首页 > 其他好文 > 详细

Binder框架(2)

时间:2015-03-19 09:58:55      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:

    通过MediaServer详细解析Binder内部实现细节。

1. MediaServer的入口函数

int main(int argc, char** argv) {
    sp<ProcessState> proc(ProcessState::self());  //获得一个ProcessState实例
    
    // MediaServer作为ServiceManager的客户端,需要向ServiceManager注册服务。
    // 调用defaultServiceManager,获取一个IServiceManager。
    sp<IServiceManager> sm = defaultServiceManager();

    AudioFlinger::instantiate();   // 初始化音频系统的AudioFlinger服务。
    MediaPlayerService::instantiate()  // 多媒体的MediaPlayerService。
    CameraService::instantiate();
    AudioPolicyService::instantiate();

    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

2. ProcessState

    ProcessState是以单例模式设计的, 每个进程只有一个ProcessState。每个进程在使用binder机制通信时,均需要维护一个ProcessState实例来描述当前进程在binder通信时的binder状态。

2.1 ProcessState的作用:

  • 打开/dev/binder设备, 对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接收数据,即提供来与内核Binder驱动交互的通道。(在构造函数中调用open_driver())。
  • 创建一个thread, 该线程负责与内核中的binder模块进行通信,称该线程为Pool Thread。(通过调用startThreadPool()函数创建并启动)
  • 为指定的handle创建一个BpBinder对象,并管理该进程中所有的BpBinder对象。(提供函数getContextObject(handle)返回)

2.2 BpBinder

     (1) BpBinder和BBinder都继承于IBinder。BpBinder是客户端用来与Server交互的代理类,p即proxy。BBinder是与proxy相对的一端,是proxy交互的目的端。BpBinder代表客户端,BBinder代表服务端。两者是一一对应的,即某个BpBinder只能与对应的BBinder交互。

    客户端通过BpBinder的transact函数向Binder设备发送调用请求的数据,它的构造函数如下:

    BpBinder(int32_t handle);
    通过BpBinder的构造函数发现,BpBinder会将当前通信中server的handle记录下来,当有数据发送时,会通知Binder Driver数据的发送目标。Binder系统通过handle值来标识对应的BBinder。

    (2) ProcessState通过如下方式来获取BpBinder对象:

    ProcessState::self()->getContextObject(handle);

    ProcessState会维护一个BpBinder的Vector mHandleToObject,每当ProcessState创建一个BpBinder的实例时,回去查询mHandleToObject,如果对应的 handle已经有binder指针,那么不再创建,否则创建binder并插入到mHandleToObject中。     (3) ProcessState创建的BpBinder实例,一般情况下会作为参数构建一个客户端的代理接口,这个代理接口的形式为BpINTERFACE,例如在与ServiceManager通信时,客户端会创建一个代理接口BpServiceManager, 由它来实现IServiceManager的业务函数。

    从sp<IServiceManager> sm = defaultServiceManager() 开始看一下创建BpServiceManager的过程。  

sp<IServiceManager> defaultServiceManager() {
    ...
    gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
    ...
    return gDefaultServiceManager;
}

     由上面可以指定ProcessState::self()->getContextObject(handle)返回一个BpBinder,所以上面代码等价于:

    gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

    interface_cast实现了BpBinderIServiceManager的关联。 interface_cast其实是一个模板函数:

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) {
    return INTERFACE::asInterface(obj);
}

     即:sp<IServiceManager> interface_cast(const sp<IBinder>& obj) {
                return IServiceManager::asInterface(obj);               // 将BnBinder作为参数传给了IServiceManager!
          }

    在IServiceManager的asInterface函数中,创建了BpServiceManager。下面看下BpServiceManager的构造:  

BpServiceManager::BpServiceManager(const sp<IBinder>& impl) 
    : BpInterface<IServiceManager>(impl) {     // 调用基类BpInterface的构造函数
}

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote) {   // 调用基类构造函数
}

BpRefBase::BpRefBase(const sp<IBinder>& o) 
   : mRemote(o.get()), mRefs(NULL), mState(0) {  //mRemote最终保存BpBinder
}

    由此可见,BpServiceManager的一个变量mRemote指向了BpBinder。

    调用了defaultServiceManager()函数之后,得到了两个重要的对象:

  • 一个是BpBinder对象,它的handle值为0.
  • 一个是BpServiceManager对象,它的mRemote值是BpBinder.

3. IServiceManager家族中的类

3.1 类继承关系

    (1) BpServiceManager同时继承于IServiceManager和BpInterface, 而BpInterface继承于BpRefBase。

    (2) BnServiceManager同时继承于IServiceManager和BBinder。MyServiceManager继承于BnServiceManager。

3.2 注意点:

  • IServiceManager,BpServiceManager, BnServiceManager都于业务逻辑相关。
  • BnServiceManager同时继承于BBinder,说明它可以直接参与Binder通信。
  • BpServiceManager派生过程看似乎与BpBinder没有关系,但实际上它的一个成员mRemote的值指向BpBinder。
  • BnServiceManager是一个虚类,需要子类来具体实现业务函数。

4.  向ServiceManager注册MediaPlayerService

4.1 业务层的工作

MediaPlayerService::instantiate() {
    defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());
}

根据前面知道,defaultServiceManager()返回的BpServiceManager,它是IServiceManager的后代。

virtual status_t BpServiceManager::addService(const String16& name, const sp<IBinder>& service) {
    Parcel data, replay;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    data.writeStrongBinder(service);
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);  // remote()返回mRemote, 即BpBinder对象。 
    return err == NO_ERROR ? reply.readInt32() : err;
}

addService()是业务层的函数,它的作用就是将请求数据打包,然后交给通信层处理。

4.2 通信层的工作

4.2.1 BpBinder与Binder设备交互的秘密就在于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);    // 实际的通信工作由IPCThreadState完成
        if (status == DEAD_OBJECT) {
             mAlive = 0;
        }
        return status;
    }
    return  DEAD_OBJECT;
}

4.2.2 IPCThreadState

IPCThreadState与Binder通信有关,每个线程有一个。

(1) IPCThreadState的构造

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self())
    , mMyThreadId(androidGetTid()) {
    pthread_setspecific(gTLS, this);       // 把自己设置到线程本地存储中去
    clearCaller();
    // mIn和mOut是两个Parcel, 看成是发送和接收命令的缓冲区   
    mIn.setDataCapicity(256);    // mIn用来接收来自Binder设备的数据
   mOut.setDataCapicity(256);    // mOut用来存储发往Binder设备的数据
}

 Pool thread会不停的查询BD中是否有数据可读,如果有将其读出并保存到mIn,同时不停的检查mOut是否有数据需要向Binder设备发送,如果有,则将其内容写入到Binder设备中。

(2) transact函数  BpBinder::transact()函数通过IPCThreadState::transact()函数来向mOut中写入数据。

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;
    ......
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    ......
    err = waitForResponse(reply);
    ......
    return err;
}
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;   // binder_transaction_data是binder设备通信的数据结构
    tr.target.handle = handle;  // handle的值传给target, 用于识别目的端,其中0是ServiceMananger的标志。
    tr.code = code;        // code是消息码,用于switch/case。
    tr.flags = binderFlags;

    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 {
        retrun (mLastError = err);
    }
    mOut.writeInt32(cmd);         // 把命令写到mOut中去,并没有直接发出去
    mOut.write(&tr, sizeof(tr));
    return NO_ERROR;
}

 函数writeTransactionData只是把addService的请求信息写到mOut中去,发送请求和接收回复由IPCThreadState::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();
        switch (cmd) {
          case BR_TRANSACTION_COMPLETE: {
             if (!reply && !acquireResult) {
                  goto finish;
             }
          }
          break;
          ......
          default: {
             err = excuteCommand(cmd);         //重点!
             if (err != NO_ERROR) {
                  goto finish;
             }
             break;
          }
        }
    }
finish:
    if (err != NO_ERROR) {
        if (acquireResult) {
               *acqueirResult = err;
               if (reply) reply->setError(err);
               mLastError = err;
        }
    }
    return err;
}

 发送了请求数据,假设收到了回复,接下来由executeCommand函数负责解析并执行mIn中的数据。

status_t IPCThreadState::executeCommand(int32_t cmd) {
    BBinder* obj;
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;

    switch (cmd) {
        case BR_ERROR: {
            result = mIn.readInt32();
            }
            break;            
        case BR_TRANSACTION: {
             binder_transaction_data tr;
             result = mIn.read(&tr, sizeof(tr));
             if (result != NO_ERROR) break;
             Parcel buffer;
             Parcel reply;
             if (tr.target.ptr) {
                 sp<BBinder> b((BBinder*)tr.cookie); // b实际上是实现BnServiceXXX的那个对象。
                 const status_t error = b->transact(tr.code, buffer, &reply, 0);
                 if (error < NO_ERROR) reply.setError(error);
             } else {
                 const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0); //the_context_object是IPCThreadState的一个全局变量。
                  if (error < NO_ERROR) reply.setError(error);
             }
         }
         break;
         case BR_DEAD_BINDER: {    // 收到Binder驱动发来的service死掉的消息。
             BpBinder* proxy = (BpBinder*)mIn.readInt32;
             proxy->sendObituary();
             mOut.writeInt32(BC_DEAD_BINDER_DONE);
             mOut.writeInt32((int32_t)proxy)
         } 
          break;
         ......
         cast BR_SPAWN_LOOPER: {
             mProcess->spawnPooledThread(false);            
         }
         break;
         default:
              result = UNKNOWN_ERROR;
              break;
    }
    ......
    if (result != NO_ERROR) {
        mLastError = result;
    }
    return result;
}

talkWithDriver()函数负责从Binder设备中读写数据。

status_t IPCThreadState::talkWithDriver(bool doReceive) {
    binder_write_read bwr;      //binder_write_read是与binder设备交换数据的结构。
    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();

    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();  // 填充接收数据缓冲区的信息。如果以后收到数据,就直接填在mIn中了。
        bwr.read_buffer =  (long unsigned int) mIn.data();
    } else {
        bwr.read_size = 0;
    }
    
    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 define(HAVE_ANDROID_OS)
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)     {
               err = NO_ERROR;
        }  else {
              err = -error;
        }
#else
            err = INVALID_OPERATION;      
#endif }
while (err == -EINTR);
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); } } if (bwr.read_consumed > 0) { mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } return NO_ERROR; } return err; }

5. startThreadPool()和joinThreadPool();

 startThreadPool()创建一个新线程PoolThread,该线程的loop中也会调用IPCThreadState::self()->joinThreadPool()来读取Binder设备查看是否有请求。另外主线程也调用joinThreadPool()读取Binder设备。

 可见当前有两个线程为Service服务。

void IPCThreadState::joinThreadPool(bool isMain) {
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); // isMain为true时,需要循环处理,先把请求信息写到mOut中去,待会一起发出去。
    androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
    status_t result;
    do {
        int32_t cmd;
        if (mIn.dataPosition() >= mIn.dataSize()) {
            size_t numPending = mPendingWeakDerefs.size();
            if (numPending > 0) {
                for (size_t i = 0; i < numPending; i++) {
                     RefBase::weakref_type* refs = mPendingWeakDerefs[i];
                     refs->decWeak(mProcess.get());
                }
                mPendingWeakDerefs.clear();
            }
            // 处理已经死亡的BBinder对象。
            numPending =  mPendingWeakDerefs.size();
            if (numPending > 0) {
                for (size_t i = 0; i < numPending; i++) {
                      BBinder* obj = mPendingStrongDerefs[i];
                      obj->decStrong(mProcess.get());  
                }
                mPendingWeakDerefs.clear();               
            }
        }
         result = talkWithDriver();
         if (result >= NO_ERROR) {
             size_T IN = mIn.dataAvail();
             if (IN < sizeof(int32_T)) {
                 continue;
             }
             cmd = mIn.readInt32();
             result = executeCommand(cmd);  //处理消息
         }
         ......
    } while(result != -ECONNERFUSED && result != -EBADF);
    
    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}

 

Binder框架(2)

标签:

原文地址:http://www.cnblogs.com/Jackwen/p/4344369.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!