Android IPC 通訊機制源碼分析【下】

來源:互聯網
上載者:User

client擷取Service的遠程IBinder介面

以CameraService為例(camera.cpp):

const sp<ICameraService>& Camera::getCameraService()

{

    Mutex::Autolock _l(mLock);

    if (mCameraService.get() == 0) {

        sp<IServiceManager> sm = defaultServiceManager();

        sp<IBinder> binder;

        do {

            binder = sm->getService(String16("media.camera"));

            if (binder != 0)

                break;

            LOGW("CameraService not published, waiting...");

            usleep(500000); // 0.5 s

        } while(true);

        if (mDeathNotifier == NULL) {

            mDeathNotifier = new DeathNotifier();

        }

        binder->linkToDeath(mDeathNotifier);

        mCameraService = interface_cast<ICameraService>(binder);

    }

    LOGE_IF(mCameraService==0, "no CameraService!?");

    return mCameraService;

}

由前面的分析可知sm是BpCameraService對象:

    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;

            LOGI("Waiting for sevice %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();

}

這裡的remote就是我們前面得到BpBinder對象。所以checkService將調用BpBinder中的transact函數:

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;

}

mHandle為0,BpBinder繼續往下調用IPCThreadState:transact函數將資料發給與mHandle相關聯的Service Manager Process。

status_t IPCThreadState::transact(int32_t handle,

                                  uint32_t code, const Parcel& data,

                                  Parcel* reply, uint32_t flags)

{

   ............................................................

    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 (err != NO_ERROR) {

        if (reply) reply->setError(err);

        return (mLastError = err);

    }

    if ((flags & TF_ONE_WAY) == 0) {

        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 tr;

    tr.target.handle = handle; //這個handle將傳遞到service_manager

    tr.code = code;

    tr.flags = bindrFlags;

。。。。。。。。。。。。。。

}

waitForResponse將調用talkWithDriver與對Binder kernel進行讀寫操作。當Binder kernel接收到資料後,service_mananger線程的ThreadPool就會啟動,service_manager尋找到 CameraService服務後調用binder_send_reply,將返回的資料寫入Binder kernel,Binder kernel。

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)

{

    int32_t cmd;

    int32_t err;

    while (1) {

        if ((err=talkWithDriver()) < NO_ERROR) break;

..............................................   

}

status_t IPCThreadState::talkWithDriver(bool doReceive)

{

   ............................................

#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

...................................................

}

通過上面的ioctl系統函數中BINDER_WRITE_READ對binder kernel進行讀寫。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.