Binder 학습 노트 (2) -default Service Manager () 는 무엇을 되돌려줍니까?

10040 단어 androidBinder
클라이언트든 서버든 머리를 먼저 호출해야 한다
sp < IServiceManager > sm = defaultServiceManager();

default Service Manager () 는 무엇을 하고 있습니까? 어떤 실례를 되돌려 줍니까?
이 함수는 frameworks/native/libs/binder/I 서비스 관리자에 정의됩니다.cpp:33
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));  <span style="color:#ff0000;">//         </span>
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    
    return gDefaultServiceManager;
}

관건적인 단계는 다음과 같이 분해할 수 있다. 1. ProcessState::self(), 2, ProcessState: getContextObject(...), 3,interfacecast(…)
1 ProcessState::self()
frameworks/native/libs/binder/ProcessState.cpp:70 
sp<ProcessState> ProcessState::self()  <span style="color:#ff0000;">//          </span>
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState;  <span style="color:#ff0000;">//        </span>
    return gProcess;
}

Process State의 구조 함수는 매우 간단합니다. 프레임워크s/native/libs/binder/Process State.cpp:339
ProcessState::ProcessState()
    : mDriverFD(open_driver())  <span style="color:#ff0000;">//      /dev/binder  ,        </span>
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        // 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.
        <strong>mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); </strong>
        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_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating."); }

ProcessState의 구조 함수는 주로 두 가지를 완성한다. 1. 초기화 목록에서 Opern 을 호출한다.driver (), 파일/dev/binder 열기;2. 파일을 메모리에 비춘다.ProcessState::self()가 단일 인스턴스를 반환합니다.
2 ProcessState::getContextObject(…)
이 함수는frameworks/native/libs/binder/ProcessState에 정의됩니다.cpp:85
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

계속 깊이 들어가기,frameworks/native/libs/binder/ProcessState/cpp:179
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);

    <strong>handle_entry* e = lookupHandleLocked(handle);</strong>  <span style="color:#ff0000;">//               </span>

    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.
        <strong>IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {</strong>  <span style="color:#ff0000;">//     b NULL,handle 0  </span> 
// 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;
            }

            <strong>b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;</strong>  <span style="color:#ff0000;">//     BpBinder(0)  </span>
        } 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;
}

따라서 getStrongProxyForHandle(0)이 되돌아오는 것은 new BpBinder(0)다.몇 가지 세부 사항을 다시 한 번 돌이켜 볼 수 있다.
2.1 ProcessState::lookupHandleLocked(int32_t handle)
이 함수는frameworks/native/libs/binder/ProcessState에 정의됩니다.cpp:166
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = NULL;
        e.refs = NULL;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return NULL;
    }
    return &mHandleToObject.editItemAt(handle);
}

구성원 변수 mHandleToObject는 배열입니다.
Vector<handle_entry>mHandleToObject;

이 함수는 그룹을 옮겨다니며handle을 찾습니다. 찾지 못하면 이 그룹에 새 요소를 삽입합니다.handle은 그룹 아래에 표시됩니다.새 요소의 binder,refs 구성원은 기본적으로 NULL이며 get StrongProxyForHandle (...) 에서 값을 부여합니다.
3 interface_cast(…)
interface_cast (...) 함수는 binder 체계에서 매우 자주 사용되며, 뒤에는 끊임없이 만날 수 있다.이 함수는frameworks/native/include/binder/IInterface.h:41
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
템플릿 매개 변수와 실참을 대입한 후:
IServiceManager::asInterface(new BpBinder(0));

매크로 IMPLEMENT 에 숨겨진 함수META_INTERFACE에서 frameworks/native/libs/binder/IServiceManager.cpp:185
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

확장 후 다음:
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) {  //       
                intr = new BpServiceManager(obj);
            }
        }
        return intr;
    }

따라서 New BpService Manager가 반환됩니다.여러 번 실을 뽑아 고치를 벗긴 후,
default Service Manager () 의 반환 값이 new BpService Manager (new BpBinder (0) 입니다. 이 결론을 기억하십시오.
BpService Manager의 계승 관계와 구조 함수, frameworks/native/libs/binder/IService Manager를 다시 한 번 살펴보겠습니다.cpp:126
class BpServiceManager : public BpInterface<IServiceManager>
frameworks/native/libs/binder/IInterface.h:62
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
BpService Manager는 BpInterface를 계승하고 후자는 BpRefBase를 계승한다.
frameworks/native/libs/binder/IServiceManager.cpp:129
BpServiceManager   BpInterface,     BpRefBase。
frameworks/native/libs/binder/IServiceManager.cpp:129
frameworks/native/include/binder/IInterface.h:134
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}
frameworks/native/libs/binder/Binder.cpp:241
BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

    if (mRemote) {
        mRemote->incStrong(this);           // Removed on first IncStrong().
        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    }
}
BpService Manager는 구조 함수를 통해 상속 관계를 따라 impl 파라미터를 기본 클래스 BpRefBase에 전달하고 기본 클래스는 데이터 구성원 mRemote에 부여한다.default Service Manager () 에서 BpService Manager 구조 함수에 전달되는 매개 변수는 new BpBinder (0) 입니다.

좋은 웹페이지 즐겨찾기