背景:Parcel.cpp是Android提供的一个容器类,通过binder传输的数据都可以写进Parcel中。但是因为Parcel中的数据最终都会copy到驱动空间,而驱动空间为每一个进程分配的内存是限的,如果Parcel中的数据量太大就会造成数据传输失败。所以,binder通信中不适宜用Parcel传输诸如图片这样的数据,如果有需求传输大容量数据,可以使用共享内存IMemory,Parcel中不仅可以装载int,float,string这样的基础数据类型,还可以装载IBinder对象,文件句柄等特殊对象。我们先来看看JavaParcel是如何装载IBinder对象
以下代码是Parcel.java 中的片段
public final class Parcel {
//JNI层Parcel.cpp 对象句柄引用
private long mNativePtr;
//对应在JNI层android_os_Parcel.cpp 文件中android_os_Parcel_create 方法
private static native long nativeCreate();
//对应在JNI层android_os_Parcel.cpp 文件中android_os_Parcel_readStrongBinder 方法
private static native IBinder nativeReadStrongBinder(long nativePtr);
//对应在JNI层android_os_Parcel.cpp 文件中android_os_Parcel_writeStrongBinder 方法
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
private Parcel(long nativePtr) {
if (DEBUG_RECYCLE) {
mStack = new RuntimeException();
}
//Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
init(nativePtr);
}
//内部提供一个获取Parcel对象方法
public static Parcel obtain() {
final Parcel[] pool = sOwnedPool;
//先看看池子里面有没有
synchronized (pool) {
Parcel p;
for (int i=0; i
流程1.在创建Java层Parcel对象时,首先在构造函数内初始化mNativePtr ,通过JNI层android_os_Parcel.cpp 文件中android_os_Parcel_create 方法将JNI层的Parcel(.cpp)对象句柄赋值给mNativePtr ;看下android_os_Parcel_create方法
static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
{
Parcel* parcel = new Parcel();
return reinterpret_cast(parcel);
}
流程2.nativeWriteStrongBinder 方法对应JNI层的android_os_Parcel.cpp文件中android_os_Parcel_writeStrongBinder()方法:
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
//将Java层持有的句柄转成JNI层的Parcel对象
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
//object 是Java层的IBinder对象
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
流程3.ibinderForJavaObject方法是什么鬼,有什么用,不急,先源码贴上该方法在android_util_Binder.cpp文件中:
sp ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//先判断下是不是Java层Binder类实例
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//判断下是不是Java层BinderProxy类实例
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
先判断下Java层传过来的IBinder对象是Binder实例还是BinderProxy实例,gBinderOffsets.mClass代表Java层的Binder类?不信,往下瞧。
流程3.1.gBinderOffsets.mClass是在android_util_Binder.cpp 中赋值的
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
//获取Java层Binder类
jclass clazz = FindClassOrDie(env, kBinderPathName);
//全局引用
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//将Java层的Binder中execTransact方法句柄赋值给 gBinderOffsets.mExecTransact
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//将Java层的Binder 中mObject字段句柄赋值给 gBinderOffsets.mObject
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
int_register_android_os_Binder 方法主要是将Java层Binder类中申明的native 方法与JNI层的关联起来,在虚拟机启动时int_register_android_os_Binder 会被注册进去,大家注意到这句代码没有
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
Binder 中mObject 这个字段是什么?在哪里赋值?在这里我们先做个记号,后面会分析道
流程3.2.gBinderProxyOffsets.mClass 在int_register_android_os_BinderProxy方法中赋值:
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
clazz = FindClassOrDie(env, kBinderProxyPathName);
//将Java层的BinderProxy 类赋值给 gBinderProxyOffsets.mClass
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
//将Java层的BinderProxy 中的mObjcet 字段赋值给 gBinderProxyOffsets.mObject
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
"Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
int_register_android_os_BinderProxy方法主要是将Java层BinderProxy类中申明的native 方法与JNI层的关联起来,在虚拟机启动时int_register_android_os_BinderProxy 会被注册进去,大家注意到这句代码没有
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
BinderProxy中mObject 这个字段是什么,在哪里赋值?在这里我们先做个记号,后面会分析道
流程3.3.回到ibinderForJavaObject方法,先分析下如果是Binder实例
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
先不分析,再看下jbh->get(env, obj) 返回的是什么,源码奉上
class JavaBBinderHolder : public RefBase
{
public:
sp get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
//将mBinder 提升为强指针
sp b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp mBinder;
};
返回的是JavaBBinder,先通过Java层的Binder类中mObject 字段值转换成JavaBBinderHolder 指针,再由该指针get 到JavaBBinder,
流程3.4还记得我们在流程3.1抛出的问题吗?mObject 是什么在哪里赋值,解铃还须系铃人,先看看Java层的Binder类有什么东西吧
Binder.java
public class Binder implements IBinder {
...
//这个分析的主角,该值是在JNI层赋值的
private long mObject;
private IInterface mOwner;
private String mDescriptor;
private native final void init();
private native final void destroy();
public Binder() {
init();
if (FIND_POTENTIAL_LEAKS) {
final Class extends Binder> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
}
}
先从构造函数下手吧,init方法是个native,好吧去android_util_Binder.cpp 中的android_util_Binder_init方法看看吧
//JNIEnv类型实际上代表了Java环境,通过这个JNIEnv* 指针,就可以对Java端的代码进行操作。例如,创建Java类中的对象,调用Java对象的方法,获取Java对象中的属性等等。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java端的代码进行操作。
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);
//参数:jobject obj的解释:
//如果native方法不是static的话,这个obj就代表这个native方法的类实例
//如果native方法是static的话,这个obj就代表这个native方法的类的class对象实例(static方法不需要类实例的,所以就代表这个类的class对象)
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);//将JavaBBinderHolder 指针赋值给JAVA 层的Binder.java 中的mObject字段
}
是不是很激动,请看
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
由流程3.1可知,gBinderOffsets.mObject 持有Java层Binder字段mObject的句柄,因此,该代码实际上是将 JavaBBinderHolder 类型指针赋值给Java层Binder字段mObject,在看下这句代码
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
现在豁然开朗了吧。
顺便,我们来分析下流程3.2抛出的BinderProxy中mObject 这个字段是什么,在哪里赋值,驾轻就熟,先看Java层的BinderProxy类,其实他是在Binder.java 文件中
final class BinderProxy implements IBinder {
.....
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
public native void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;
public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
.....
}
你会发现并没有mObject字段,其实他用的外部类Binder 中的mObject字段,但是我们在android_util_Binder.cpp文件中并没有找到类似初始化赋值,(其实是有赋值的)I have dream,如果是BinderProxy实例流程则执行
(IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
很明显,不做解释;
流程4回到流程2,由流程3可知,ibinderForJavaObject返回的是JavaBBinder 继承 BBinder (本流程暂时默认ibinderForJavaObject方法中的流程是走if中的流程),回顾下流程2的代码
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
//将Java层持有的句柄转成JNI层的Parcel对象
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
//object 是Java层的IBinder对象,如果object 是Binder对象,则下面代码可以等效
// const status_t err = parcel->writeStrongBinder(JavaBBinder );
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
跟着代码来到Parcel.cpp中的writeStrongBinder方法
status_t Parcel::writeStrongBinder(const sp& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
流程5.继续看ProcessState::self()
sp ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
看看ProcessState构造函数
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
, mDriverFD(open_driver(driver))//打开Binder驱动
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD = -1;
mDriverName.clear();
}
}
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
这两个函数本次先不详细分析,简单来说就是打开Binder驱动,在映射一块内存地址,将该地址首地址返回,再看看flatten_binder方法
status_t flatten_binder(const sp& /*proc*/,
const sp& binder, Parcel* out)
{
//Parcel中存放的binder对象,以此数据结构来表征
flat_binder_object obj;
if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
/* minimum priority for all nodes is nice 0 */
//所有节点的最低优先级都是0
obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
} else {
/* minimum priority for all nodes is MAX_NICE(19) */
//所有节点的最低优先级最大19
obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
}
if (binder != NULL) {
//如果binder是BinderProxy对象,此处为null
IBinder *local = binder->localBinder();
if (!local) {
//如果binder为BBinder及其子类实例对象此处返回null
BpBinder *proxy = binder->remoteBinder();
if (proxy == NULL) {
ALOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
//标明是个代理
obj.type = BINDER_TYPE_HANDLE;
obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
obj.handle = handle;
obj.cookie = 0;
} else {
//标明是个BBinder
obj.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast(local->getWeakRefs());
obj.cookie = reinterpret_cast(local);
}
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = 0;
obj.cookie = 0;
}
return finish_flatten_binder(binder, obj, out);
}
流程6.本函数其实就是对flat_binder_object 结构数据赋值,那我们先来看看该结构体吧
/*
* This is the flattened representation of a Binder object for transfer
* between processes. The 'offsets' supplied as part of a binder transaction
* contains offsets into the data where these structures occur. The Binder
* driver takes care of re-writing the structure type and data as it moves
* between processes.
*/
struct flat_binder_object {
struct binder_object_header hdr;
__u32 flags;
/* 8 bytes of data. */
union {
binder_uintptr_t binder; /* local object */
__u32 handle; /* remote object */
};
/* extra data associated with local object */
binder_uintptr_t cookie;
};
看此结构体的注释,大概知道了,其实也最终解密了writeStrongBinder 的目的,就是将BBinder或者BpBinder 对象转换成flat_binder_object 结构体,最终flat_binder_object 会通过Parcel.cpp 的writeObject 方法,写入到mData,mObject中,看看Parcel.cpp 的writeObject
status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
{
const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
const bool enoughObjects = mObjectsSize < mObjectsCapacity;
if (enoughData && enoughObjects) {
restart_write:
// 如果空间足够,他把前面组装的flat_binder_object实体追加到mData里
*reinterpret_cast(mData+mDataPos) = val;
// remember if it's a file descriptor
if (val.type == BINDER_TYPE_FD) {
if (!mAllowFds) {
// fail before modifying our object index
return FDS_NOT_ALLOWED;
}
mHasFds = mFdsKnown = true;
}
// Need to write meta-data?
if (nullMetaData || val.binder != 0) {
// mObjects记录每次向mData追加的flat_binder_object的偏移位置
mObjects[mObjectsSize] = mDataPos;
acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
mObjectsSize++;
}
return finishWrite(sizeof(flat_binder_object));
}
if (!enoughData) {
//空间不够,申请空间
const status_t err = growData(sizeof(val));
if (err != NO_ERROR) return err;
}
if (!enoughObjects) {
//超出数组长度,扩容
size_t newSize = ((mObjectsSize+2)*3)/2;
if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
if (objects == NULL) return NO_MEMORY;
mObjects = objects;
mObjectsCapacity = newSize;
}
goto restart_write;
}
通过以上流程,我们分析了一个Binder对象由Java层的Parcel 再由JNI层的android_os_Parcel.cpp转换成BBinder,最终写入了JNI层Parcel.cpp的mData 中,那么这个mData怎么被送去驱动层的呢?在Parcel.cpp中有个mOut,有什么用,是不是mData就是通过mData out出去,我们先放一放,后面会有专门一章节分析,我们先看看readStrongBinder 这个方法,由于有了分析writeStrongBinder 的经验,后面的流程我可能会简化一些
流程7Parcel.java 中readStrongBinder 方法的native实现是在android_os_Parcel.cpp 中的android_os_Parcel_readStrongBinder 方法
android_os_Parcel.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
nativePtr 的意义与流程1中分析的一样,可以参看流程1,javaObjectForIBinder这个方法似乎有点熟悉,还记得ibinderForJavaObject方法么,其实二者有异曲同工之妙,我们先看看parcel->readStrongBinder(),在Parcel.cpp文件中
sp Parcel::readStrongBinder() const
{
sp val;
// Note that a lot of code in Android reads binders by hand with this
// method, and that code has historically been ok with getting nullptr
// back (while ignoring error codes).
readNullableStrongBinder(&val);
return val;
}
status_t Parcel::readNullableStrongBinder(sp* val) const
{
return unflatten_binder(ProcessState::self(), *this, val);
}
流程7.1还记得之前分析的flatten_binder吗,看到unflatten_binder是不是很熟悉的感觉,
Parcel.cpp
status_t unflatten_binder(const sp& proc,
const Parcel& in, sp* out)
{
const flat_binder_object* flat = in.readObject(false);
if (flat) {
switch (flat->type) {
case BINDER_TYPE_BINDER:
*out = reinterpret_cast(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
这里又出现了flat_binder_object这个结构体,在写的时候也需要先将BBinder转换成该结构体,读的时候也需要先转换成该结构体,再看看readObject函数吧
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
{
const size_t DPOS = mDataPos;
if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
const flat_binder_object* obj
= reinterpret_cast(mData+DPOS);
mDataPos = DPOS + sizeof(flat_binder_object);
if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
// When transferring a NULL object, we don't write it into
// the object list, so we don't want to check for it when
// reading.
ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
return obj;
}
// Ensure that this object is valid...
binder_size_t* const OBJS = mObjects;
const size_t N = mObjectsSize;
size_t opos = mNextObjectHint;
if (N > 0) {
ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
this, DPOS, opos);
// Start at the current hint position, looking for an object at
// the current data position.
if (opos < N) {
while (opos < (N-1) && OBJS[opos] < DPOS) {
opos++;
}
} else {
opos = N-1;
}
if (OBJS[opos] == DPOS) {
// Found it!
ALOGV("Parcel %p found obj %zu at index %zu with forward search",
this, DPOS, opos);
mNextObjectHint = opos+1;
ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
return obj;
}
// Look backwards for it...
while (opos > 0 && OBJS[opos] > DPOS) {
opos--;
}
if (OBJS[opos] == DPOS) {
// Found it!
ALOGV("Parcel %p found obj %zu at index %zu with backward search",
this, DPOS, opos);
mNextObjectHint = opos+1;
ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
return obj;
}
}
ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
this, DPOS);
}
return NULL;
}
对比下流程6中的writeObject,简直就是一个逆向操作,回到流程7,此时flat的值应该是BINDER_TYPE_HANDLE,为什么是这个值呢,这个是要去Binder驱动层分析才知道,本次先不分析,接着看代码
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast(out->get()), *flat, in);
getStrongProxyForHandle这个是不是很熟悉,走进去瞧瞧
ProcessState.cpp
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp result;
AutoMutex _l(mLock);
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;
}
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;
}
返回一个BpBinder,回到流程7javaObjectForIBinder(env, parcel->readStrongBinder()); 等效于javaObjectForIBinder(env,new BpBinder(handler)),在看看javaObjectForIBinder方法
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
// One of our own!
jobject object = static_cast(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %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 %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) {
LOGDEATH("objectForBinder %p: created new proxy %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;
}
还记得gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor在哪里初始化的吗,参看流程3.2,javaObjectForIBinder方法最终返回的是Java层的BinderProxy对象。
总结从Java层的角度来看,我们向内核写入的是Binder对象,最终返回的是BinderProxy对象,其中各个变化在以上流程中都简单分析了下,后面章节我会针对以上流程做更加详细的分析,毕竟我们现在还很多事没有弄清楚,比如流程7.1中的我们留下的一个问题,1.flag的值为什么是BINDER_TYPE_HANDLE呢,这个要求驱动代码中去分析;2:内核到底对我们写入的Binder如何管理的;3.为什么Binder比其他的跨进程通讯要快;4.内存共享是最快的,那Android为什么还要以Binder机制作为基础通讯;
参考:https://www.jianshu.com/p/59a3ca77f71d
参考:http://www.mamicode.com/info-detail-1586374.html
参考:https://mr-cao.gitbooks.io/android/content/android-binder.html