servicemanager的客戶端代理: BpServiceManager

servicemanager做爲一個守護進程在開機時被啓動,此後就能夠說servicemanager的服務端已經就緒,其它服務(如MediaService等具體服務)就能夠向servicemanager註冊本身了,爲了實現和servicemanager的交互,在libbinder庫中也爲servicemanager提供了客戶端(即代理部分),相關核心類就是下圖中的IServiceManager和BpServiceManager。android

這篇筆記就來分析servicemanager代理端的典型流程實現。ide

獲取servicemanager代理對象;
註冊服務;
獲取服務;
獲取servicemanager代理
// client經過IServiceManager和servicemanager通訊,經過該接口獲取BpServiceManager(IServiceManager的子類)對象
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL)
        return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            // IServiceManager是根據BpBinder對象構造出來的,這裏的interface_cast轉換也很關鍵
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}函數

全局的gDefaultServiceManager表示每一個進程只會持有一個BpServiceManager對象指針,實際上也只須要有一個該對象。有兩步核心操做:ui

ProcessState::self()->getContextObject(NULL);
interface_cast<IServiceManager>();
getContextObject()
// 獲取BpBinder對象
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    // 參數0很是重要,指定了要獲取的服務的句柄,0表示servicemanager
    return getStrongProxyForHandle(0);
}this

// 當前進程持有的全部其它service的句柄
Vector<handle_entry>mHandleToObject;
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;代理

    AutoMutex _l(mLock);
    // 獲取或者新建handle對應的handle_entry
    handle_entry* e = lookupHandleLocked(handle);
    if (e != NULL) {
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  See comment
        // in getWeakProxyForHandle() for more info about this.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                // Special case for context manager...
                // The context manager is the only object for which we create
                // a BpBinder proxy without already holding a reference.
                // Perform a dummy transaction to ensure the context manager
                // is registered before we create the first local reference
                // to it (which will occur when creating the BpBinder).
                // If a local reference is created for the BpBinder when the
                // context manager is not present, the driver will fail to
                // provide a reference to the context manager, but the
                // driver API does not return status.
                //
                // Note that this is not race-free if the context manager
                // dies while this code runs.
                //
                // TODO: add a driver API to wait for context manager, or
                // stop special casing handle 0 for context manager and add
                // a driver API to get a handle to the context manager with
                // proper reference counting.
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            // 建立BpBinder對象
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }
    return result;
}指針

整個過程的核心在BpBinder::create(),建立一個BpBinder對象,傳入的handle爲0,0特指servicemanager。code

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

對應到這裏就是IServiceManager::asInterface(),該函數並無直接實現,libbinder提供了兩個宏,其中包含了該函數的實現,這兩個宏分別爲DECLARE_META_INTERFACE()和IMPLEMENT_META_INTERFACE()。這兩個宏的展開過程再也不細述,直接看最終的結果:server

::android::sp<IServiceManager> IServiceManager::asInterface(const ::android::sp<::android::IBinder>& obj)
{
    ::android::sp<IServiceManager> intr;
    if (obj != NULL) {
        intr = static_cast<IServiceManager*>(obj->queryLocalInterface(IServiceManager::descriptor).get());
        if (intr == NULL) {
            // 返回的就是BpServiceManager對象,obj就是包裝了0句柄的BpBinder對象
            intr = new BpServiceManager(obj);
        }
    }
    return intr;
}

註冊服務
通常,服務註冊過程以下面的示例代碼所示(來自BinderService::publish()):

// 向系統註冊服務
static status_t publish(bool allowIsolated = false, int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT)
{
    // 獲取BpServiceManager對象
    sp<IServiceManager> sm(defaultServiceManager());
    // 調用addService()方法,前兩個入參分別爲服務名字和服務對象指針
    return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags);
}

addService()是由BpServiceManager實現的。

virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority)
{
    Parcel data, reply;
    // 向servicemanager發送該調用請求
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    // 要註冊的服務信息
    data.writeString16(name);
    data.writeStrongBinder(service);
    data.writeInt32(allowIsolated ? 1 : 0);
    data.writeInt32(dumpsysPriority);
    // 調用BpBinder中的transact()
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    return err == NO_ERROR ? reply.readExceptionCode() : err;
}

remote()函數是BpServiceManager從BpRefBase中繼承來的,返回的就是封裝了server端句柄的BpBinder對象指針。

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) {
        // 調用的是IPCThreadState中的transact()
        status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }
    return DEAD_OBJECT;
}

最後經過IPCThreadState中的transact()將要傳遞給servicemager的數據寫入binder驅動。

獲取服務
客戶端要想調用服務端提供的接口,首先要獲取服務端的代理,這是經過BpServiceManager::getService()實現的。

// 入參就是服務的名字
virtual sp<IBinder> getService(const String16& name) const
{
    sp<IBinder> svc = checkService(name);
    if (svc != NULL) return svc;
    // 判斷是不是廠商本身實現的binder驅動
    const bool isVendorService = strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
    const long timeout = uptimeMillis() + 5000;
    if (!gSystemBootCompleted) {
        char bootCompleted[PROPERTY_VALUE_MAX];
        property_get("sys.boot_completed", bootCompleted, "0");
        gSystemBootCompleted = strcmp(bootCompleted, "1") == 0 ? true : false;
    }
    // retry interval in millisecond.
    const long sleepTime = gSystemBootCompleted ? 1000 : 100;
    // 最多等待5s,獲取封裝了服務端句柄的BpBinder對象
    int n = 0;
    while (uptimeMillis() < timeout) {
        n++;
        if (isVendorService) {
            ALOGI("Waiting for vendor service %s...", String8(name).string());
            CallStack stack(LOG_TAG);
        } else if (n%10 == 0) {
            ALOGI("Waiting for service %s...", String8(name).string());
        }
        usleep(1000*sleepTime);
        sp<IBinder> svc = checkService(name);
        if (svc != NULL) return svc;
    }
    ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
    return NULL;
}

如上,實際調用的是checkService():

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(); }  

相關文章
相關標籤/搜索