Android-Native-Server 启动和注册详细分析

以mediaService为实例来讲解:
mediaService的启动入口 是一个 传统的  main()函数
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\av\media\mediaserver\main_mediaserver.cpp
步骤:、
1.获取ProcessState实例的强引用  proc
2.获取到一个BpServiceManager ServiceManager的代理类
3.初始化服务:AudioFlinger MediaPlayerService  CameraService  AudioPolicyService
4.开启线程池
int main( int argc,  char * * argv)
{
     //sp  是 strongpointer 是一个强引用指针
     //获取ProcessState实例的强引用
    sp <ProcessState > proc(ProcessState : :self());
     //获取到一个BpServiceManager(BpBinder的子类)(servicerManager的代理对象)
    sp <IServiceManager > sm  = defaultServiceManager();
    ALOGI( "ServiceManager: %p", sm.get());
     //AudioFlinger服务初始化
    AudioFlinger : :instantiate();
     //MediaPlayerService服务初始化
    MediaPlayerService : :instantiate();
     //CameraService服务初始化
    CameraService : :instantiate();
     //AudioPolicyService服务初始化
    AudioPolicyService : :instantiate();
     //Server进程开启线程池 ?
    ProcessState : :self() - >startThreadPool();
    IPCThreadState : :self() - >joinThreadPool();
}
 
2.(callby 1) ProcessState::self()是一个单例模式,第一次调用时,gProcess  == null 会出发ProcessState的构造函数
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\native\libs\binder\ProcessState.cpp
sp <ProcessState > ProcessState : :self()
{
    Mutex : :Autolock _l(gProcessMutex);
     if (gProcess  != NULL) {
         return gProcess;
    }
    gProcess  =  new ProcessState;
     return gProcess;
}
 
3.(callby 2) ProcessState的实例化会打开Binder设备并进行内存映射。
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\native\libs\binder\ProcessState.cpp
ProcessState : :ProcessState()
     : mDriverFD(open_driver()) //这里会打开Binder设备
    , mVMStart(MAP_FAILED)
    , mManagesContexts( false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted( false)
    , mThreadPoolSeq( 1)
{
     if (mDriverFD  > =  0) { //表示打开open_drover()函数打开Binder设备并映射好虚拟内存空间成功
         // 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
 
 
4.(callby 3)Binder设备的打开函数。用来打开Binder设备。
源码位置E:\src_android\android_4.1.1_r1\android_4.1.1_r1\frameworks\native\libs\binder\ProcessState.cpp
static  int open_driver()
{
     int fd  = open( "/dev/binder", O_RDWR);
     if (fd  > =  0) {
         //又是系统调用,具体功能就不知道了。
        fcntl(fd, F_SETFD, FD_CLOEXEC);
         int vers;
         //获取Binder设备的版本号。
        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;
        }
         //通过Binder设备的系统调用,设置最大的线程数量
        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;
}
 
5.(callby 1) 返回一个BpServiceMamager.是ServiceManager的代理类。
源码位置:IServiceManager.cpp
interface _cast是一个复杂的宏定 把BpBidner封装成BpServiceManager,BpBidner存储在BpServiceManager父类的 BpRefBase 中的mRemote 中并提供remote()函数来返回BpBidner变量
sp <IServiceManager > defaultServiceManager()
{
     if (gDefaultServiceManager  != NULL)  return gDefaultServiceManager;
 
    {
        AutoMutex _l(gDefaultServiceManagerLock);
         if (gDefaultServiceManager  == NULL) {
            gDefaultServiceManager  = interface_cast <IServiceManager >(
                ProcessState : :self() - >getContextObject(NULL));
        } //ProcessState::self()单例函数调用,getContextObject返回的是一个BpBidner
         //interface_cast<IServiceManager> 函数把BpBidner封装成BpServiceManager,BpBidner被放在
         //BpServiceManager父类的 BpRefBase 中的mRemote 中并提供remote()函数来返回BpBidner变量
    }
 
     return gDefaultServiceManager;
}
 
AudioFlinger::instantiate();这一句是对AudioFlinger的初始化(下面的MediaPlayerService等也是同个道理)
AudioFlinger继承了BinderService<AudioFlinger> 和BnAudioFlinger
Binder<AudioFlinger> 提供了两个静态函数在这里被用到 
instantiate  和  publish,publish被instantiate简单调用而已。
源码:BinderService.h
template < typename SERVICE >
class BinderService
{
public :
     //调用了IServiceManager的addService方法,实现服务的注册
     static status_t publish( bool allowIsolated  =  false) {
        sp <IServiceManager > sm(defaultServiceManager());
         return sm - >addService(String16(SERVICE : :getServiceName()),  new SERVICE(), allowIsolated);
    }
 
     static  void publishAndJoinThreadPool( bool allowIsolated  =  false) {
        sp <IServiceManager > sm(defaultServiceManager());
        sm - >addService(String16(SERVICE : :getServiceName()),  new SERVICE(), allowIsolated);
        ProcessState : :self() - >startThreadPool();
        IPCThreadState : :self() - >joinThreadPool();
    }
     //简单调用了publish()方法。
     static  void instantiate() { publish(); }
 
     static status_t shutdown() {
         return NO_ERROR;
    }
};
 
publish中调用了人 defaultServiceManager。获取到serviceManager。
在Android的Binder框架中,可以说有三种C/S模式:
1.Client:serviceManager  Server: Binder设备驱动
2.Client:AudioFlinger    Server: serviceManager
3.Client:用户            Server: AudioFlinger
下面publish是第一种C/S模型,实现了serviceManage和Binder设备驱动的交互。通过 sm - > addService提交事务。
static status_t publish( bool allowIsolated = false ) {
        sp < IServiceManager > sm(defaultServiceManager());
         return sm - > addService(String16(SERVICE : : getServiceName()), new SERVICE(), allowIsolated);
    }
 
下面是sm->addservice的具体实现:
Parcel是进程之间通信用的数据格式,data是client传给server的数据,reply是存储Server处理后返回的结果数据。
IServiceManager::getInterfaceDescriptor());是由宏实现的,返回的是"android.os.IserviceManager"
name是当前服务名称"media.audio_fligner"
service:是AudioFlinger实例
remote()返回的是BpBinder实例
virtual status_t addService( const String16 & name,  const sp <IBinder > & service,
             bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager : :getInterfaceDescriptor());//"android.os.IserviceManager"
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated  ?  1  :  0);
         //调用remote()返回一个IBinder对象,在调用BpBinder的事物处理函数transact
         //来处理这个事物
        status_t err  = remote() - >transact(ADD_SERVICE_TRANSACTION, data,  &reply);
         return err  == NO_ERROR  ? reply.readExceptionCode()  : err;
    }
 
 
transact中调用了 IPCThreadState::self()->transact,真正对事务进行处理是在IPCThreadState中进行的。
源码: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中有两个重要的函数:
writeTransactionData 和  waitForResponse
writeTransactionData :负责对与Binder设备通讯的数据进行封装。
waitForResponse:负责与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) {
        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 (reply) {
            err  = waitForResponse(reply);
        }  else {
            Parcel fakeReply;
            err  = waitForResponse( &fakeReply);
        }
       ..............
.........省略部分代码.........
............... 
     return err;
}
 
 
writeTransactionData 顾名思义就是写入事务所需要的数据。
与Binder设备进行数据的交互是另外一种数据结构binder_transaction_data,不同于进程之间进行通讯的数据结构Parcel
所以在这里就必须把Parcel转换成binder_transaction_data 。
最终是把binder_transaction_data 写进ServiceManager进程在Binder设备申请的内存映射区mOut里面。
上面就把要给Binder设备的数据封装好,放在一个Binder知道的地方。
接下来,就要让Binder去取数据,并做处理。
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);
    mOut.write( &tr,  sizeof(tr));
 
     return NO_ERROR;
 
waitForResponse是另一个重要函数,里面有一个while循环,每次循环的开始都会执行talkWithDriver函数,然后去读取 cmd = mIn.readInt32(); 其返回的是一个command,意思是通过talkWithDriver不断地去访问Binder设备,“催促Binder设备快点处理我的事务”,然后通过mIn.readInt32()得到事务处理结果,再用swich语句来处理,Binder反馈回来的结果,其中case BR_REPLY:是我们最终想要得到的反馈结果,意思是Binder已经对我们的事务做了处理,并有结果了,在这个分支里面,我们 把结果写进 Parcel * reply,并通过go finish结束函数。
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()  ==  0continue;
 
        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中进行内核的Binder通信。
关键函数是:ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) 进行系统调用。
最后把返回的数据写进 mIn  。
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
status_t IPCThreadState : :talkWithDriver( bool doReceive)
{
    ALOG_ASSERT(mProcess - >mDriverFD  > =  0"Binder driver is not opened");
 
    binder_write_read bwr;
 
     // Is the read buffer empty?
     const  bool needRead  = mIn.dataPosition()  > = mIn.dataSize();
 
     // We don't want to write anything if we are still reading
     // from data left in the input buffer and the caller
     // has requested to read the next data.
     const size_t outAvail  = ( !doReceive  || needRead)  ? mOut.dataSize()  :  0;
 
    bwr.write_size  = outAvail;
    bwr.write_buffer  = ( long  unsigned  int)mOut.data();
 
     // This is what we'll read.
     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;
    }
 
     // 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_LOG_COMMANDS() {
            alog  <<  "About to read/write, write size = "  << mOut.dataSize()  << endl;
        }
# if  defined(HAVE_ANDROID_OS)
         if (ioctl(mProcess - >mDriverFD, BINDER_WRITE_READ,  &bwr)  > =  0)
            err  = NO_ERROR;
         else
            err  =  -errno;
# else
        err  = INVALID_OPERATION;
# endif
        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;
    }
 
     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);
        }
        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;
}
 
最后是开启线程池:
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
startThreadPool:
mThreadPoolStarted = true;设置当前线程池的启动标志。
spawnPooledThread中开启一个新线程sp<Thread> t = new PoolThread(isMain);//PoolThread是Thread的子类。
并执行线程函数来运行线程  t->run(buf);
最后IPCThreadState::self()->joinThreadPool();把主线程也加入了线程池。!!!
void ProcessState : :startThreadPool()
{
    AutoMutex _l(mLock);
     if ( !mThreadPoolStarted) {
        mThreadPoolStarted  =  true;
        spawnPooledThread( true);
    }
}
 
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
        char buf[16];
        snprintf(buf, sizeof(buf), "Binder_%X", s);
        ALOGV("Spawning new pooled thread, name=%s\n", buf);
        sp<Thread> t = new PoolThread(isMain);
        t->run(buf);
    }
}
上面提到的宏定义及其实现:
# define DECLARE_META_INTERFACE(INTERFACE)                               \
     static  const android : :String16 descriptor;                          \
     static android : :sp <I##INTERFACE > asInterface(                       \
             cons
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值