这一章通过WifiService来分析一下在Java framework中如何注册Service,在分析注册WifiService之前,先来看一下WifiService相关的类
下面是我们以前分析过的WifiService的注册代码:
try { Slog.i(TAG, "Wi-Fi Service"); wifi = new WifiService(context); ServiceManager.addService(Context.WIFI_SERVICE, wifi); } catch (Throwable e) { reportWtf("starting Wi-Fi Service", e); }
这里首先构造一个WifiService对象,在构造WifiService对象时,我们前面已经看过的构造函数了,这里主要来看一下它的两个父类的构造函数:
public Stub() { this.attachInterface(this, DESCRIPTOR); } public void attachInterface(IInterface owner, String descriptor) { mOwner = owner; mDescriptor = descriptor; }
public Binder() { init(); }
Binder的构造函数主要就是调用init去做初始化的工作,init的实现在android_util_Binder.cpp中,我们后面再来分析。
这里调用ServiceManager的addService方法,第一个参数Context.WIFI_SERVICE是"wifi"字串;第二个参数是WifiService对象,WifiService是继承于Binder的。来看addService方法:
public static void addService(String name, IBinder service) { try { getIServiceManager().addService(name, service, false); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } }
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
在分析BinderInternal.getContextObject()前,我们先来分析一下android_util_Binder.cpp这个文件,它是Java层的binder和Native层的binder中间的桥梁。android_util_Binder.cpp的初始化函数是register_android_os_Binder,它在AndroidRuntime初始化时被加载执行。在register_android_os_Binder方法中,又分为三个步骤,第一步映射Java层的Binder类,并注册其中的Native函数;第二步映射Java层的BinderInternal类,并注册其中的Native函数;第三步映射Java层的BinderProxy类,并注册其中的Native函数:
int register_android_os_Binder(JNIEnv* env) { if (int_register_android_os_Binder(env) < 0) return -1; if (int_register_android_os_BinderInternal(env) < 0) return -1; if (int_register_android_os_BinderProxy(env) < 0) return -1; jclass clazz; clazz = env->FindClass("android/util/Log"); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.util.Log"); gLogOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gLogOffsets.mLogE = env->GetStaticMethodID( clazz, "e", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I"); assert(gLogOffsets.mLogE); clazz = env->FindClass("android/os/ParcelFileDescriptor"); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor"); gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); clazz = env->FindClass("android/os/StrictMode"); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.StrictMode"); gStrictModeCallbackOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gStrictModeCallbackOffsets.mCallback = env->GetStaticMethodID( clazz, "onBinderStrictModePolicyChange", "(I)V"); LOG_FATAL_IF(gStrictModeCallbackOffsets.mCallback == NULL, "Unable to find strict mode callback."); return 0; }
static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz; clazz = env->FindClass(kBinderPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder"); gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderOffsets.mObject); return AndroidRuntime::registerNativeMethods( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }首先通过JNI的FindClass把Binder.class加载进来,然后在gBinderOffsets保存Binder.class的引用和Binder的execTransact函数ID,通过mObject保存Binder中mObject变量的ID,这个变量用于以后存储JNI层JavaBBinderHolder的地址。最后调用registerNativeMethods将Java层的函数和Native层的函数建立好映射关系。int_register_android_os_BinderInternal和int_register_android_os_BinderProxy与int_register_android_os_Binder实现差不多,通过上面三个函数,我们可以在JNI层看到下面的数据关系:
结构体 | 变量名 | 解释 |
gBinderOffsets | mClass | 保存Binder.class的ref |
mExecTransact | 保存Binder.class的execTransact函数ID | |
mObject | 保存Binder.class的mObject成员ID,实际保存JavaBBinderHolder的地址 | |
gBinderInternalOffsets | mClass | 保存BinderInternal.class的ref |
mForceGc | 保存BinderInternal.class的forceBinderGc函数ID | |
gBinderProxyOffsets | mClass | 保存BinderProxy.class的ref |
mConstructor | 保存BinderProxy.class的init函数ID | |
mSendDeathNotice | 保存BinderProxy.class的sendDeathNotice函数ID | |
mObject | 保存BinderProxy.class的mObject成员ID,实际保存BpBinder地址 | |
mSelf | 保存BinderProxy.class的mSelf成员ID,用于注册将BpBinder和BinderProxy绑定 | |
mOrgue | 保存BinderProxy.class的mOrgue成员ID,实际保存DeathRecipientList地址 |
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { sp<IBinder> b = ProcessState::self()->getContextObject(NULL); return javaObjectForIBinder(env, b); }
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { if (val == NULL) return NULL; if (val->checkSubclass(&gBinderOffsets)) { return object; } AutoMutex _l(mProxyLock); jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = jniGetReferent(env, object); if (res != NULL) { ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res); return res; } LOGDEATH("Proxy object %p of IBinder %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) { env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); val->incStrong((void*)javaObjectForIBinder); jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); incRefsCreated(env); } return object; }
static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ServiceManagerProxy(obj); }
private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = new ServiceManagerProxy(BinderProxy); return sServiceManager; }
public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); data.writeStrongBinder(service); data.writeInt(allowIsolated ? 1 : 0); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
public static Parcel obtain() { final Parcel[] pool = sOwnedPool; synchronized (pool) { Parcel p; for (int i=0; i<POOL_SIZE; i++) { p = pool[i]; if (p != null) { pool[i] = null; if (DEBUG_RECYCLE) { p.mStack = new RuntimeException(); } return p; } } } return new Parcel(0); } public final void recycle() { if (DEBUG_RECYCLE) mStack = null; freeBuffer(); final Parcel[] pool; if (mOwnsNativeParcelObject) { pool = sOwnedPool; } else { mNativePtr = 0; pool = sHolderPool; } synchronized (pool) { for (int i=0; i<POOL_SIZE; i++) { if (pool[i] == null) { pool[i] = this; return; } } } }
private Parcel(int nativePtr) { if (DEBUG_RECYCLE) { mStack = new RuntimeException(); } //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack); init(nativePtr); } private void init(int nativePtr) { if (nativePtr != 0) { mNativePtr = nativePtr; mOwnsNativeParcelObject = false; } else { mNativePtr = nativeCreate(); mOwnsNativeParcelObject = true; } }
static jint android_os_Parcel_create(JNIEnv* env, jclass clazz) { Parcel* parcel = new Parcel(); return reinterpret_cast<jint>(parcel); }
在mNativePtr就保存中Native层的Parcel对象的地址,当使用完调用recycle时,先调用JNI层的freeBuffer()来释放Native层的Parcel对象所申请的存储数据的内存空间,然后将它自己放到Parcel pool中,这样下一次再用Parcel时,就不要再次分配了。来看一下freeBuffer()的实现:
static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jint nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { parcel->freeData(); } } void Parcel::freeData() { freeDataNoInit(); initState(); }
static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jint nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { const jchar* str = env->GetStringCritical(name, 0); if (str != NULL) { parcel->writeInterfaceToken(String16(str, env->GetStringLength(name))); env->ReleaseStringCritical(name, str); } } }
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { signalExceptionForError(env, clazz, err); } } }
static void android_os_Binder_init(JNIEnv* env, jobject obj) { JavaBBinderHolder* jbh = new JavaBBinderHolder(); if (jbh == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return; } ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); jbh->incStrong((void*)android_os_Binder_init); env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); }
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetIntField(obj, gBinderOffsets.mObject); return jbh != NULL ? jbh->get(env, obj) : NULL; } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; }
因为WifiService是继承于Binder,首先从WifiSerivce对象的mObject上取出JavaBBinderHolder对象,然后调用它的get方法:
class JavaBBinderHolder : public RefBase { public: sp<JavaBBinder> get(JNIEnv* env, jobject obj) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { b = new JavaBBinder(env, obj); mBinder = b; ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n", b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount()); } return b; } sp<JavaBBinder> getExisting() { AutoMutex _l(mLock); return mBinder.promote(); } private: Mutex mLock; wp<JavaBBinder> mBinder; };
在第一次进入到get方法是mBinder并没有赋值,所以它的promote方法返回NULL,所以这里先创建一个JavaBBinder对象,并赋值给mBinder,然后返回。这里的JavaBBinder是继承于BBinder,所以它是一个Bn端,并实现了onTransact方法。至于如何调用这里的onTransact方法,我们下一章再来分析。这里只需要记住在Binder.java中的mObject变量保存了JavaBBinderHolder对象,在JavaBBinderHolder对象中的mBinder中保存了一个JavaBBinder对象,在JavaBBinder保存了真正的WifiService对象。回到android_os_Parcel_writeStrongBinder函数中,接着调用Native层Parcel的writeStrongBinder方法将上面的JavaBBinder写入。再回到ServiceManagerProxy的addService方法中,接着调用mRemote.transact方法,这里的mRemote就是BinderProxy对象,所以来看BinderProxy的transact,它的实现也在android_util_Binder.cpp中。
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { if (dataObj == NULL) { } Parcel* data = parcelForJavaObject(env, dataObj); if (data == NULL) { return JNI_FALSE; } Parcel* reply = parcelForJavaObject(env, replyObj); if (reply == NULL && replyObj != NULL) { return JNI_FALSE; } IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } ALOGV("Java code calling transact on %p in Java object %p with code %d\n", target, obj, code); status_t err = target->transact(code, *data, reply, flags); if (err == NO_ERROR) { return JNI_TRUE; } else if (err == UNKNOWN_TRANSACTION) { return JNI_FALSE; } signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/); return JNI_FALSE; }