Binder(2)--sayHello之BinderProxy的创建过程.md
- 参考资料
- 简介
- 一. asInterface方法
- 二. sayHello
-
三. BinderProxy的创建过程
- 3.1 publishServiceLocked
- 3.2 publishService写入参数
- 3.3 SystemServer接收参数
- 四. 总结
参考资料
- Android Binder详解 https://mr-cao.gitbooks.io/android/content/android-binder.html
- msm-4.14 Code https://github.com/android-linux-stable/msm-4.14/blob/9c4b6ed1b229cfc35e5c3e5815e297b7f519cf93/drivers/android/binder.c
简介
接上文,首先回顾一下IBinder相关接口的类图:
现在我们Client进程已经拿到Server端IDemoInterface中的IBinder对象,但是这个IBinder对象到底是哪个呢,Stub本身?还是Proxy亦或是Proxy中的mRemote?
还是看sayHello的调用过程先:
override fun onServiceConnected(p0: ComponentName?, p1: IBinder?) {
Log.d("Client", "DemoService connected")
// 远程服务连接成功,打个招呼
// 1.1 这个asInterface是做了什么操作呢?
val mProxyBinder = IDemoInterface.Stub.asInterface(p1)
try {
// 2.1 sayHello!
mProxyBinder.sayHello(5000, "Hello?")
} catch (e:RemoteException) {
}
}
一. asInterface方法
1.1 IDemoInterface.Stub.asInterface
public static com.oneplus.opbench.server.IDemoInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
// 1.2 生成IInterface
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.oneplus.opbench.server.IDemoInterface))) {
return ((com.oneplus.opbench.server.IDemoInterface)iin);
}
// 1.3 转换成Proxy对象
return new com.oneplus.opbench.server.IDemoInterface.Stub.Proxy(obj);
}
这个方法是自动生成的,看起来就是通过IBinder生成一个IInterface或者Proxy?
1.2 Binder.queryLocalInterface
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
if (mDescriptor != null && mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
看类图我们也知道,只有Binder实现了IBinder接口,而也只有IDemoInterface.Stub继承了Binder。这么说起来,SystemServer回传的IBinder对象实际上是服务端的IDemoInterface.Stub?然而mOwner此时还是null的,注意我们现在在Client进程中。这里我们直接debug client进程发现queryLocalInterface返回的null值,而且传入的IBinder的类型居然是BinderProxy的!这里什么时候返回非null,传入的IBinder是什么时候变成BinderProxy的呢,先留个疑问。
1.3 创建IDemoInterface.Stub.Proxy对象
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
明白了,现在这个mRemote对象实际上是指代的BinderProxy!
二. sayHello
2.1 Proxy.sayHello
@Override public void sayHello(long aLong, java.lang.String aString) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
// 按顺序写入参数, 注意DESCRIPTOR
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeLong(aLong);
_data.writeString(aString);
// 2.2 实质上是mRemote起作用的,在1.3中我们通过Debug知道这个其实是BinderProxy对象
boolean _status = mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().sayHello(aLong, aString);
return;
}
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
2.2 BinderProxy.transact
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
// ......
// 2.3 忽略其他代码,这个是call了一个native方法,通过JNI调用
return transactNative(code, data, reply, flags);
// ......
}
2.3 android_util_Binder.cpp#android_os_BinderProxy_transact
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
// ......
// 2.3.1 首先从名字中可以推出是获取远程通信的目标
IBinder* target = getBPNativeData(env, obj)->mObject.get();
// ......
// 2.3.2 继续
status_t err = target->transact(code, *data, reply, flags);
// .....
}
2.3.1 android_util_Binder.cpp#getBPNativeData
struct BinderProxyNativeData {
// Both fields are constant and not null once javaObjectForIBinder returns this as
// part of a BinderProxy.
// The native IBinder proxied by this BinderProxy.
sp<IBinder> mObject;
// Death recipients for mObject. Reference counted only because DeathRecipients
// hold a weak reference that can be temporarily promoted.
sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
};
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
jmethodID mGetInstance;
jmethodID mSendDeathNotice;
// Object state.
jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
// 其实就是读取BinderProxy对象中保存的long类型的mNativeData数据
// 然后强制转换成BinderProxyNativeData类型
return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
}
这里并不知道BinderProxy从哪儿来的,Native层也没有定义,应该就是指代java层的BinderProxy。
2.3.2 IBinder#transact
virtual status_t transact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) = 0;
这里我们知道getBpNativeData中的mObject是IBinder类型的。但是是一个虚函数,没有具体实现,怎么往下查呢。
Native的Debug方式也有,但是总归不方便,那我们先梳理一下Native层关于IBinder的类图吧。注意现在我们还是在Client进程内的。
IBinder相关类之间的关系大致理清楚了,从这个函数名称getBPNativeData可以猜出来应该是指代的BpBinder!
但是怎么确认呢,那我们回到Client App和Server App建立通信的过程中,溯源BinderProxy。
三. BinderProxy的创建过程
3.1 publishServiceLocked
- ServerApp: ActivityThread.handleBindService(BindServiceData data)
- SystemServer: ActivityManagerService.publishService(IBinder token, Intent intent, IBinder service)
- SystemServer: ActiveService.publishServiceLocked(ServiceRecord r, Intent intent, IBinder service)
private void handleBindService(BindServiceData data) {
// 这个mService就是Service在被调用onCreate方法的时候存入的
Service s = mServices.get(data.token);
if (DEBUG_SERVICE)
Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
// 3.1.1 所以这个onBind,就是Service中我们实现的onBind方法了
// 这里的binder就是对应我们实现的IDemoInterface.Stub
IBinder binder = s.onBind(data.intent);
// 告诉SystemServer该服务已准备就绪
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
// 这里就是rebind
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
// ......
}
}
3.1.1 服务端的Stub初始化
class DemoBinder:IDemoInterface.Stub() {
override fun sayHello(aLong: Long, aString: String?) {
Log.d("DemoService", "$aString:$aLong")
}
}
// 看看这个Stub的初始化过程
private val binder = DemoBinder()
override fun onBind(intent: Intent?): IBinder? {
// 所以Service中的onBind含义就是通知到AMS
// 本服务已准备继续,随时可以工作
return binder
}
还要注意的是,初始化DemoBinder过程,会调用父类的构造函数哦:
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
// 噢噢,这个mOwner就是在这里保存的!
// 它代表的就是IDemoInterface.Stub类的对象,其实就是DemoBinder
mOwner = owner;
mDescriptor = descriptor;
}
但是这里还是没有找到BinderProxy对象的创建。不过我们知道,Binder通信是通过往Parcel中写入数据的;
而AMS.publishService函数中最后一个参数就是IBinder类型的。
3.2 publishService写入参数
通过查看IActivityManager.aidl文件编译后生成的IActivityManager.Stub.Proxy.class(想想为啥不是Stub而是Proxy)文件可以知道这个函数的具体内容:
public void publishService(IBinder token, Intent intent, IBinder service) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken("android.app.IActivityManager");
_data.writeStrongBinder(token);
if (intent != null) {
_data.writeInt(1);
intent.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
// 3.1.3 IBinder对象是通过writeStrongBinder方法写入的
// 注意这个IBinder就是Service实现的onBind方法中返回的, 就是IDemoInterface.Stub类型
_data.writeStrongBinder(service);
boolean _status = this.mRemote.transact(32, _data, _reply, 0);
if (!_status && IActivityManager.Stub.getDefaultImpl() != null) {
IActivityManager.Stub.getDefaultImpl().publishService(token, intent, service);
return;
}
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
3.2.1 Parcel.writeStrongBinder
public final void writeStrongBinder(IBinder val) {
// 这里的mNativePtr就是此Parcel在Native的对应标识
nativeWriteStrongBinder(mNativePtr, val);
}
看样子直接去了Native层干活去了。
3.2.2 android_os_Parcel#android_os_Parcel_writeStrongBinder
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
// 转成Native的Parcel
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// 3.2.2.1 注意这个ibinderForJavaObject方法,将java层IBinder转成Native层的
// 3.2.3 然后是保存这个Native的IBinder
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
3.2.2.1 android_util_Binder#ibinderForJavaObject
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
// Instance of Binder?
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
// 3.2.2.2 返回一个IBinder
return jbh->get(env, obj);
}
// Instance of BinderProxy?
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return getBPNativeData(env, obj)->mObject;
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
这块首次出现了BinderProxy,不过当前我们还处于Service App进程对吧,而且上层传入的IBinder明显只是一个IDemoInterface.Stub类型。
所以这里还是将这个jobject转换成了JavaBBinderHolder!不过我们有理由猜测,BinderProxy是在AMS所处的SystemServer进程中转换的。
3.2.2.2 android_util_Binder#JavaBBinderHolder#get
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
// 3.2.2.3 创建JavaBBinder
b = new JavaBBinder(env, obj);
if (mVintf) {
::android::internal::Stability::markVintf(b.get());
}
if (mExtension != nullptr) {
b.get()->setExtension(mExtension);
}
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
// 直接返回的JavaBBinder,说明JavaBBinder继承了IBinder
return b;
}
3.2.2.3 创建Native层的IBinder对象-JavaBBinder
JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
// 这些先不管
gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
gcIfManyNewRefs(env);
}
我们在看看现在Native层和IBinder有关系的类的类图:
果然JavaBBinder继承了IBinder。回到#3.2.2中,继续往下就是writeStrongBinder了。
3.2.3 Parcel#writeStrongBinder
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flattenBinder(val);
}
status_t Parcel::flattenBinder(const sp<IBinder>& binder)
{
flat_binder_object obj;
// ......
if (binder != nullptr) {
// 3.2.3.1 是local还是remote?
BBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == nullptr) {
ALOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.hdr.type = BINDER_TYPE_HANDLE;
obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
obj.handle = handle;
obj.cookie = 0;
} else {
// 进入!
if (local->isRequestingSid()) {
obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
}
// 注意这里的type,是BINDER_TYPE_BINDER!
obj.hdr.type = BINDER_TYPE_BINDER;
// 保存BBinder的弱引用,这个是干啥用的?
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
// 保存BBinder对象
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
} else {
obj.hdr.type = BINDER_TYPE_BINDER;
obj.binder = 0;
obj.cookie = 0;
}
// 3.2.4 完成IBinder的写入
return finishFlattenBinder(binder, obj);
}
这里对local和remote存在不同的处理方式,不过我们先仅仅关注其中一个分支。
3.2.3.1 IBinder#localBinder
我们这里的IBinder就是JavaBBinder类的对象,前面我们看过了JavaBBinder的初始化
BBinder* IBinder::localBinder()
{
return nullptr;
}
// 注意IBinder调用的是这个
BBinder* BBinder::localBinder()
{
return this;
}
因为这里的IBinder指针是指向其子类的子类JavaBBinder,然后其子类BBinder实现了虚函数localBinder,而JavaBBinder并没有。
所以这里是local的!
3.2.4 Parcel#finishFlattenBinder
flatten的意思是压平,其实可以理解为打包,将JavaBBinder打包然后发送出去。
status_t Parcel::finishFlattenBinder(
const sp<IBinder>& binder, const flat_binder_object& flat)
{
// 写入内存区域,这一块没有接触过,暂时先不管,后面研究
// 理解为将IBinder保存到内存中的某个特定区域
status_t status = writeObject(flat, false);
if (status != OK) return status;
internal::Stability::tryMarkCompilationUnit(binder.get());
return writeInt32(internal::Stability::get(binder.get()));
}
到这里我们知道了Java层的IBinder对象是如何通过Parcel保存到Native中的。
3.3 SystemServer接收参数
这里我们先不去细究通信的过程,因为这本身就是一次Binder通信。先看AMS收到Server App发布Service的IBinder对象是什么。
还是通过看编译后生成的IActivityManager.Stub.Class文件中对应的publishService方法,注意我们现在切换到了SystemServer进程(忽略进程切换过程)。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
// ......
data.enforceInterface(descriptor);
// 读取IBinder对象,不过这个是token, 不是我们想要的Service的IBinder
// 用过Binder通信知道,是按顺序来读写的,所以我们看最后一个IBinder
iBinder11 = data.readStrongBinder();
if (0 != data.readInt()) {
intent6 = (Intent)Intent.CREATOR.createFromParcel(data);
} else {
intent6 = null;
}
// 3.3.1 这里就是我们想要的Service的IBinder了
iBinder26 = data.readStrongBinder();
publishService(iBinder11, intent6, iBinder26);
reply.writeNoException();
return true;
// ......
}
3.3.1 Parcel.readStrongBinder
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
还是直接切到Native.
3.3.2 android_os_Parcel#android_os_Parcel_readStrongBinder
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// 3.3.2.1 先看Parce->readStrongBinder
// 3.3.3 将IBinder转换成jobject
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
3.3.2.1 Parcel#readStrongBinder
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
// 暂时不明确IBinder指代的是具体哪个子类吼
readNullableStrongBinder(&val);
return val;
}
status_t Parcel::readStrongBinder(sp<IBinder>* val) const
{
status_t status = readNullableStrongBinder(val);
if (status == OK && !val->get()) {
status = UNEXPECTED_NULL;
}
return status;
}
status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
{
// 来了,解压的过程
return unflattenBinder(val);
}
3.3.2.2 Parcel#unflattenBinder
status_t Parcel::unflattenBinder(sp<IBinder>* out) const
{
// 从内存区域中读取当前位置的数据
const flat_binder_object* flat = readObject(false);
// 存在
if (flat) {
switch (flat->hdr.type) {
// 我们在flatten中的Type就是这个!
case BINDER_TYPE_BINDER: {
// 转成IBinder,没有问题,我们存入的JavaBBinder,其父类的父类就是IBinder
sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
// 3.3.2.3 完成数据解压
return finishUnflattenBinder(binder, out);
}
case BINDER_TYPE_HANDLE: {
sp<IBinder> binder =
ProcessState::self()->getStrongProxyForHandle(flat->handle);
return finishUnflattenBinder(binder, out);
}
}
}
return BAD_TYPE;
}
这个地方留个心眼哦,这里的flat->hdr.type真的还是原来的BINDER_TYPE_BINDER吗?
3.3.2.3 Parcel#finishUnflattenBinder
status_t Parcel::finishUnflattenBinder(
const sp<IBinder>& binder, sp<IBinder>* out) const
{
int32_t stability;
status_t status = readInt32(&stability);
if (status != OK) return status;
status = internal::Stability::set(binder.get(), stability, true /*log*/);
if (status != OK) return status;
// out指向这个内存区域
*out = binder;
return OK;
}
所以这个IBinder到底是什么类型的呢?先回到#3.3.2中,继续readStrongBinder的过程
3.3.3 android_util_Binder#javaObjectForIBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
// ......
// 3.3.3.1 这里决定是不是直接返回JavaBBinder的类型
if (val->checkSubclass(&gBinderOffsets)) {
// It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
jobject object = static_cast<JavaBBinder*>(val.get())->object();
LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
return object;
}
// 3.3.4 终于看到和BinderProxy相关的了, 至少名字上看都有关系
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
// 将从内存中读取的IBinder对象存起来
nativeData->mObject = val;
// 3.3.5 调用到java方法mGetInstance,生成BinderProxy!
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
// ......
// 所以这里最终返回是BinderProxy对象对应JNI的jobject.
return object;
}
3.3.3.1 IBinder#checkSubclass
bool IBinder::checkSubclass(const void* /*subclassID*/) const
{
return false;
}
// JavaBBinder:
bool checkSubclass(const void* subclassID) const
{
// 3.3.3.2 gBinderOffsets的初始化
return subclassID == &gBinderOffsets;
}
这里思考一个问题,注意我们现在已经处于SystemServer进程了,这里的IBinder指向一块内存区域,是从Server App中拷贝而来的,与JavaBBinder数据保持一致。
那我们强制转换转成了IBinder,然后调用IBinder中的函数是调用IBinder中函数实现还是JavaBBinder中的函数实现呢?
3.3.3.2 android_util_Binder#int_register_android_os_Binder
首先gBinderOffsets是bindernative_offsets_t类型的结构体,其在int_register_android_os_Binder中被填充数据。
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderPathName);
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
"()Ljava/lang/String;");
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
我们知道,在Java中,每个进程都有自己的虚拟机环境,所以对于不同进程来说,JNIEnv肯定也是不同的,这就导致gBinderOffsets也是不同的。
所以对于3.3.3.1中checkSubclass来说,返回的就是false了。
3.3.4 创建BinderProxyNativeData
struct BinderProxyNativeData {
// Both fields are constant and not null once javaObjectForIBinder returns this as
// part of a BinderProxy.
// The native IBinder proxied by this BinderProxy.
sp<IBinder> mObject;
// Death recipients for mObject. Reference counted only because DeathRecipients
// hold a weak reference that can be temporarily promoted.
sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
};
哦噢,空欢喜?这里只是一个结构体,将IBinder和DeathRecipientList组合起来。
3.3.5 gBinderProxyOffsets.mGetInstance => BinderProxy.getInstance
private static BinderProxy getInstance(long nativeData, long iBinder) {
BinderProxy result;
synchronized (sProxyMap) {
try {
result = sProxyMap.get(iBinder);
if (result != null) {
return result;
}
// 创建BinderProxy对象!
result = new BinderProxy(nativeData);
} catch (Throwable e) {
// We're throwing an exception (probably OOME); don't drop nativeData.
NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
nativeData);
throw e;
}
NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
// The registry now owns nativeData, even if registration threw an exception.
sProxyMap.set(iBinder, result);
}
return result;
}
private BinderProxy(long nativeData) {
// 所以这个nativeData原来是代表的BinderProxyNativeData
mNativeData = nativeData;
}
通过JNI调用到Java方法,最终生成BinderProxy对象。
四. 总结
到这里我们就理清了BinderProxy这个是怎么来的了。总结一下:
- Server App实现Service的onBind方法,返回一个IBinder对象,这个IBinder对象是继承了某个aidl接口的Stub类,记为StubIBinder
- Server App调用publishService,将StubIBinder通过一系列方法,在Native层转成JavaBBinder,保存在Parce的内存区域中
- Binder驱动拷贝Parcel并将其传给SystemServer进程(这个过程我们稍后分析)
- SystemServer接收到Parcel内存数据,将其中JavaBBinder所在的内存区域强制转成IBinder类型,并将其保存为Java层的BinderProxy对象
同理我们知道Client App通过调用bindService获取了一个IBinder对象,那这个IBinder对象也是BinderProxy类型的, 只不过这里有点点小差异:
SystemServer通过IServiceConnection向Client App发送Server App注册的BinderProxy对象时,在Parcel.writeStrongBinder过程中,存入cookie的是BinderProxy:
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
// 是否为Binder对象
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh->get(env, obj);
}
// 是否为BinderProxy对象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
// SystemServer向Client App发送Server App的BinderProxy对象,走这里
return getBPNativeData(env, obj)->mObject;
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
那么在接下来打包flattenBinder的过程中, type 的类型其实是 BINDER_TYPE_HANDLE
status_t Parcel::flattenBinder(const sp<IBinder>& binder)
// ......
// 注意此时我们身处SystemServer进程,传入的IBinder实际上是对应BinderProxy
BBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
if (proxy == nullptr) {
ALOGE("null proxy");
}
const int32_t handle = proxy ? proxy->handle() : 0;
obj.hdr.type = BINDER_TYPE_HANDLE;
obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
obj.handle = handle;
obj.cookie = 0;
} else {
if (local->isRequestingSid()) {
obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
}
obj.hdr.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
// ......
}
4.1 新的疑问
哦吼,新的问题来了,这个binder->localBinder()调用的到底是那个方法呢?IBinder, BBinder中都有实现。
如果是直接拷贝的话,那么按理说也是会调用到BBinder的localBinder,这样这里还是个local!
如果拷贝后在新进程中调用的是IBinder的localBinder,那么接下来的remoteBinder也是IBinder的,还是返回null!
这样也说不通,因为如果remoteBinder返回的也是空,那么打包后传入的信息就不能识别Server App的IDemoInterface了。
这里曾困扰我一段时间,这个IBinder到底是什么是我们理解Binder通信的基础。
按照网上一大堆的文章来说,从Binder通信到了另一个进程,那么BBinder就会转成了BpBinder。
然而我们梳理了上层代码,并没有发现这个转变过程。在Parcel整个压缩和解包的过程中都没有发现将IBinder强制转成BpBinder。
4.2 binder驱动
其实这里是在驱动层做的处理:android/kernel/msm-4.19/drivers/android/binder.c
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, int reply,
binder_size_t extra_buffers_size)
{
// ......
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
buffer_offset += sizeof(binder_size_t)) {
// ......
switch (hdr->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
struct flat_binder_object *fp;
fp = to_flat_binder_object(hdr);
ret = binder_translate_binder(fp, t, thread);
// ......
}
// ......
}
static int binder_translate_binder(struct flat_binder_object *fp,
struct binder_transaction *t,
struct binder_thread *thread)
{
// ......
if (fp->hdr.type == BINDER_TYPE_BINDER)
// 这里,如果读取的hdr.type是BINDER_TYPE_BINDER
// 将会被改成BINDER_TYPE_HANDLE!!!
fp->hdr.type = BINDER_TYPE_HANDLE;
else
fp->hdr.type = BINDER_TYPE_WEAK_HANDLE;
// ......
}
在驱动层传输数据的时候会加工一次!怪不得上层找不到任何信息,这个可真的是太容易误导了。
4.3 SystemServer => Parcel#unflattenBinder
所以在 #3.3.2.2 中 Parcel#unflattenBinder 解包数据时,对IBinder对象的处理是另外一条路径了:
status_t Parcel::unflattenBinder(sp<IBinder>* out) const
{
// 从内存区域中读取当前位置的数据
const flat_binder_object* flat = readObject(false);
// 存在
if (flat) {
switch (flat->hdr.type) {
case BINDER_TYPE_BINDER: {
sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
return finishUnflattenBinder(binder, out);
}
case BINDER_TYPE_HANDLE: {
// 注意此时收到的数据是经过Binder驱动加工过的,我们现在是在SystemServer进程
// 所以这个hdr.type从BINDER_TYPE_BINDER转成了BINDER_TYPE_HANDLE!
// 这里解包,注意flat_binder_object这个结构体,他里面的binder和handle是被组合成union结构的!
// 所以封包的时候写存入的binder就是此时读取的handle,这也代表了Server App中对应的BBinder
sp<IBinder> binder =
ProcessState::self()->getStrongProxyForHandle(flat->handle);
// 这里我们在回到#3.3.2中android_os_Parcel#android_os_Parcel_readStrongBinder
// 就可以知道,其实SystemServer自始至终都是保存了来自Server App的BBinder相同数据但是转成了BpBinder的IBinder对象
return finishUnflattenBinder(binder, out);
}
}
}
return BAD_TYPE;
}
这里有个疑问吼,我们看这个flat_binder_object结构的内容:
typedef __u32 binder_size_t;
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;
};
这个handle是一个__u32类型的数据,说明该变量占4字节。
4.3.1 ProcessState#getStrongProxyForHandle(int32_t handle)
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
// 4.3.2 从mHandleToObject中获取handle对应的handle_entry
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder;
// 第一次当然是null的
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
if (status == DEAD_OBJECT)
return nullptr;
}
// 4.3.3 创建BpBinder!!!
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
// 这个result就是新创建的BpBinder,或者之前创建缓存的BpBinder
return result;
}
4.3.2 ProcessState#lookupHandleLocked
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
// mHandleToObject 是Vector类型的数据集合
const size_t N=mHandleToObject.size();
if (N <= (size_t)handle) {
handle_entry e;
e.binder = nullptr;
e.refs = nullptr;
status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
if (err < NO_ERROR) return nullptr;
}
return &mHandleToObject.editItemAt(handle);
}
这里传入的handle其实是Server App在打包数据时,获取的:obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()), 然后经过驱动加工,可以视为BBinder的映射BpBinder的Token. 这里的细节我们后面分析。
一般来说每个BBinder都不一样(为什么呢,涉及到binder驱动以及Android的智能指针),所以,这里的mHandleToObject是缓存IBinder对象,防止频繁创建销毁消耗资源。
4.3.3 创建BpBinder
BpBinder* BpBinder::create(int32_t handle) {
int32_t trackedUid = -1;
// sCountByUidEnabled默认是false的,SystemServer进程是再开机过程中打开的
if (sCountByUidEnabled) {
// 获取Server App的UID
trackedUid = IPCThreadState::self()->getCallingUid();
// 接下来是判断Server App是否存在过多的binder proxy对象
// 默认2500个, 对于SystemServer进程是6000个(也是开机过程中设置的nSetBinderProxyCountWatermarks)
AutoMutex _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[trackedUid];
if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) {
if (sBinderProxyThrottleCreate) {
return nullptr;
}
} else {
if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
getuid(), trackedUid, trackedValue);
sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
if (sLimitCallback) sLimitCallback(trackedUid);
if (sBinderProxyThrottleCreate) {
ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
" count drops below %d",
trackedUid, getuid(), sBinderProxyCountLowWatermark);
return nullptr;
}
}
}
// 该UID创建了新的BpBinder
sTrackingMap[trackedUid]++;
}
return new BpBinder(handle, trackedUid);
}
BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
: mHandle(handle)
, mStability(0)
, mAlive(1)
, mObitsSent(0)
, mObituaries(nullptr)
, mTrackedUid(trackedUid)
{
ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
// 给此BpBinder新增一个弱引用
IPCThreadState::self()->incWeakHandle(handle, this);
}
最后补上一张IBinder类图:
了解了IBinder转换过程的原理,BinderProxy的生成过程,也知道了BBinder和BpBinder的映射关系,接下来就是在Client App和Server App之间的通信了。
下一篇: 大白话聊聊mysql的悲观锁