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


    Android-Native-Server 启动和注册详细分析
     
     
    以mediaService为实例来讲解:
    mediaService的启动入口 是一个 传统的  main()函数
    源码位置E:src_androidandroid_4.1.1_r1android_4.1.1_r1frameworksavmediamediaservermain_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_androidandroid_4.1.1_r1android_4.1.1_r1frameworks ativelibsinderProcessState.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_androidandroid_4.1.1_r1android_4.1.1_r1frameworks ativelibsinderProcessState.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. ");
                close(mDriverFD);
                mDriverFD = -1;
            }
    #else
            mDriverFD = -1;
    #endif
        }
     
        LOG_ALWAYS_FATAL
     
     
    4.(callby 3)Binder设备的打开函数。用来打开Binder设备。
    源码位置E:src_androidandroid_4.1.1_r1android_4.1.1_r1frameworks ativelibsinderProcessState.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 ", 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() == 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中进行内核的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 ", 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(                       
                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; }       
     
  • 相关阅读:
    Grid 拾遗
    WPF 依赖属性
    升级cordova
    oracle比较一行的最大值或最小值
    nginx完全关闭log
    hive计算周一的日期
    查看linux文件目录的大小和文件夹包含的文件数
    linux设置服务器时间同步
    oracle取出多个字段列中的最大值和最小值
    oracle SQL语句取本周本月本年的数据
  • 原文地址:https://www.cnblogs.com/chenchuangfeng/p/3236388.html
Copyright © 2020-2023  润新知