ServiceManager是安卓中一個重要的類,用於管理全部的系統服務,維護着系統服務和客戶端的binder通訊。
對此陌生的能夠先看系統服務與ServiceManager來了解應用層是如何使用ServiceManager的。
咱們能夠經過 ServiceManager.getService(String name)來獲取服務,返回的是一個Binder對象,用於與系統作遠程通訊java
public static IBinder getService(String name) { try { IBinder service = sCache.get(name); if (service != null) { return service; } else { return getIServiceManager().getService(name); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; }
這裏的sCache是一個Map,若是cache中有這個Binder對象就直接返回了,若是沒有就調用getIServiceManager().getService(name)來獲取android
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
能夠看到這裏返回了一個IServiceManager,它也是一個Binder對象,最終獲取服務用的就是這個Binder對象。
而且是經過BinderInternal.getContextObject()來拿到Binder對象的。緩存
/** * Return the global "context object" of the system. This is usually * an implementation of IServiceManager, which you can use to find * other services. */ public static final native IBinder getContextObject();
它實如今frameworks/base/core/jni/android_util_Binder.cpp文件中:cookie
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
這裏應該不難理解,先獲取一個native層的IBinder,再將該對象轉換成Java Object返回給調用者,在Java層拿到的應該是一個ServiceManagerProxy對象。
先看第一部獲取native層的IBinder對象:函數
sp b = ProcessState::self()->getContextObject(NULL);
在ProcessState的構造函數中,會經過open文件操做函數打開設備文件/dev/binder,而且返回來的設備文件描述符保存在成員變量mDriverFD中,供後續在IPCThreadState中使用
須要注意的是這裏傳了一個NULL,也就是0,下面會提到它的做用:
[ProcessState.cpp]工具
sp ProcessState::getContextObject(const sp& /*caller*/) { return getStrongProxyForHandle(0); } sp ProcessState::getStrongProxyForHandle(int32_t handle) { sp result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked(handle); if (e != NULL) { IBinder* b = e->binder; if (b == NULL || !e->refs->attemptIncWeak(this)) { if (handle == 0) { Parcel data; status_t status = IPCThreadState::self()->transact( 0, IBinder::PING_TRANSACTION, data, NULL, 0); if (status == DEAD_OBJECT) return NULL; } b = new BpBinder(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; }
能夠看到,最終返回的對象是:b = new BpBinder(handle); 並將handler傳了進去
這裏的handler便是以前傳進來的0,表明一個句柄,這個句柄是有特殊意義的。
咱們知道在Java層有兩類Binder,一個是Binder對象用於服務端創建的對象,一個是BinderProxy是客戶端取到的Binder對象。
native層也有兩類Binder,一個是BpBinder,一個是BBinder:
BpBinder是客戶端用來與Server交互的代理類,p即Proxy的意思,
BBinder則是proxy交互的目的端,
而且他們是一一對應的。
繼續回到代碼,建立了一個BpBinder對象,傳進去的hande爲0,那麼他是怎麼找到對應的BBinder的呢?
事實上,handle表明了通訊的目的端,這個0表明的就是ServiceManager所對應的BBinder。
繼續往下看,經過上面獲取的對象建立一個Java層的Binder對象並返回:
[android_util_Binder.cpp]ui
return javaObjectForIBinder(env, b)
繼續看建立Java層對象的過程:
[android_util_Binder.cpp]this
jobject javaObjectForIBinder(JNIEnv* env, const sp& val) { if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) { // One of our own! jobject object = static_cast<JavaBBinder*>(val.get())->object(); LOGDEATH("objectForBinder {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p: it's our own {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p!\n", val.get(), object); return object; } // For the rest of the function we will hold this lock, to serialize // looking/creation/destruction of Java proxies for native Binder proxies. AutoMutex _l(mProxyLock); // Someone else's... do we know about it? jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = jniGetReferent(env, object); if (res != NULL) { ALOGV("objectForBinder {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p: found existing {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p!\n", val.get(), res); return res; } LOGDEATH("Proxy object {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p of IBinder {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p no longer in working set!!!", object, val.get()); android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { LOGDEATH("objectForBinder {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p: created new proxy {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}p !\n", val.get(), object); // The proxy holds a reference to the native object. env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get()); val->incStrong((void*)javaObjectForIBinder); // The native object needs to hold a weak reference back to the // proxy, so we can retrieve the same proxy if it is still active. jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Also remember the death recipients registered on this proxy sp drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; }
能夠看到有兩處返回語句,跳過第一處取緩存對象,直接往下看:atom
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
這裏建立了一個BinderProxy對象,這時候這個對象與Native層用於通訊的BpBinder沒有任何關係,繼續往下看:spa
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
這裏是把BpBinder對象的地址賦值給了BinderProxy對象的mObject字段,經過這種手段將Java層的對象與Native層的對象關聯在了一塊兒。
而後咱們操做Java層BinderProxy對象的native方法的時候,就能定位到對應的BpBinder對象了。
而且把這個Java層的對象放到了BpBinder對象中,以後就不用再次建立了:
jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup);
回到Java層代碼,咱們經過下面代碼來獲取一個能夠調用的ServiceManager對象:
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
看過Android IPC 機制的應該知道,這裏返回的是一個ServiceManagerProxy對象,裏面持有一個名爲面Remote的IBiner對象,從上面能夠看到這個mRemote就是以前拿到的BinderProxy,真正進行進程間通訊的時候會調用BinderProxy的transact方法,而後在它的內部調用transactNative方法。
再次來到native層,調用以下方法:
[android_util_Binder.cpp]
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { //... IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } bool time_binder_calls; int64_t start_millis; if (kEnableBinderSample) { time_binder_calls = should_time_binder_calls(); if (time_binder_calls) { start_millis = uptimeMillis(); } } status_t err = target->transact(code, *data, reply, flags); if (kEnableBinderSample) { if (time_binder_calls) { conditionally_log_binder_call(start_millis, target, code); } } if (err == NO_ERROR) { return JNI_TRUE; } else if (err == UNKNOWN_TRANSACTION) { return JNI_FALSE; } signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize()); return JNI_FALSE; }
爲何是這個方法呢?這裏在簡單的書一下jni,有靜態註冊和動態註冊兩種方法,這裏用的是動態註冊,會用到以下定義:
static const JNINativeMethod gBinderProxyMethods[] = { /* name, signature, funcPtr */ {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder}, {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive}, {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor}, {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact}, {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}, {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath}, {"destroy", "()V", (void*)android_os_BinderProxy_destroy}, };
包括Java層方法名,方法簽名,調用的函數指針。
這裏不過多展開了,繼續:
IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
能夠看到這裏用到了以前保存在BinderProxy中的的mObject字段,拿到了原始的BpBinder對象。
而後調用BpBinder對象的transact方法:
status_t err = target->transact(code, *data, reply, flags);
下面看BpBinder的transact方法:
[BpBinder.cpp]
tatus_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; }
BpBinder只是一個轉發工具,最終由IPCThreadState執行:
status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
而且帶上了表明BBinder對象的mHandle。
[IPCThreadState.cpp]
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 (err == NO_ERROR) { LOG_ONEWAY(">>>> SEND from pid {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}d uid {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}d {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}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 0 if (code == 4) { // relayout ALOGI(">>>>>> CALLING transaction 4"); } else { ALOGI(">>>>>> CALLING transaction {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}d", code); } #endif if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } #if 0 if (code == 4) { // relayout ALOGI("<<<<<< RETURNING transaction 4"); } else { ALOGI("<<<<<< RETURNING transaction {936b63963a8c9f2b24063da536a495a32039ff9ed9d82cacc18dd4741407c351}d", code); } #endif IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand " << handle << ": "; if (reply) alog << indent << *reply << dedent << endl; else alog << "(none requested)" << endl; } } else { err = waitForResponse(NULL, NULL); } return err; }
有兩個方法調用須要關注:
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
err = waitForResponse(NULL, NULL);
一個是寫數據,一個是等待相應。在此以前假設咱們知道:
每一個線程都有一個IPCThreadState,每一個IPCThreadState中都有一個mIn、一個mOut,其中mIn是用來接收來自Binder設備的數據的,而mOut則是用來存儲發往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.ptr = 0; /* Don't pass uninitialized stack data to a remote process */ 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(binder_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 = reinterpret_cast(statusBuffer); tr.offsets_size = 0; tr.data.ptr.offsets = 0; } else { return (mLastError = err); } mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); return NO_ERROR; }
特別注意這裏:tr.target.handle = handle;通訊的目標值是handle,也就是以前傳的0;最後寫入到mOut中;
真正執行在waitForResponse方法中,這個方法是一個死循環,一直在讀取mIn的數據,最後會根據code進行分發,調用executeCommand方法,
在executeCommand方法內部獲取BBinder調用transact:
error = reinterpret_cast(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
這裏的mIn與mOut即是真正的進程間通訊,能夠查看IPCThreadState::talkWithDriver方法與Binder驅動通訊,使用ioctl方式的方式讀寫/dev/binder虛擬設備。
關於Binder的深刻分析,下次有機會再分享。
那麼ServiceManager的服務是如何註冊的呢?
在native層能夠經過下面代碼獲取IServiceManager:
spsm = defaultServiceManager()
而後各個服務模塊會經過IServiceManager的addService方法將各自的模塊註冊到系統這個惟一的ServiceManager中
[IServiceManager.cpp]
sp defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); while (gDefaultServiceManager == NULL) { gDefaultServiceManager = interface_cast( ProcessState::self()->getContextObject(NULL)); if (gDefaultServiceManager == NULL) sleep(1); } } return gDefaultServiceManager; }
能夠看到這個是單例,經過下面代碼初始化:
gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL));
PocessState::self()->getContextObject(NULL)這個以前分析過了獲取的是ServiceManager的BpBinder對象,而後轉換成BpServiceManager對象供其餘服務模塊使用,這裏用到了模板函數和宏定義最終返回的是 new BpServiceManager(ProcessState::self()->getContextObject(NULL))。