Android-Native-Server 啓動和註冊詳細分析

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() == 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\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(                       \
             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; }       \
相關文章
相關標籤/搜索