binder-JAVA层机制

根据之前分析过的cpp代码,以及编写了JAVA层的代码,笔者画了一个图进行了分层

JAVA中,RPC层的代码是直接通过aidl文件生成的,cpp部分是需要我们自己编写的

那么在JAVA中就存在两个问题,就是图中红色的部分

client是如何发送数据给server的
Service是如何读取到数据,如何调用到onTransact函数的

通过这两个问题去分析源码,就能理解JAVA层的机制了

client流程

既然我们获取服务使用 ServieManager 的getService,我们就分析它(不知道为什么版本28这个类里面的返回都是null,估计在哪里做了什么骚操作了吧)

1
2
3
4
5
6
7
8
9
10
11
12
13
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就是一个HashMap
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();

主要看 getIServiceManager

1
2
3
4
5
6
7
8
9
10
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}

// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
1
public static final native IBinder getContextObject();

getContextObject 是一个native方法,以后看到这个native,我们就应该知道,它是调用cpp的代码,就是一个JNI调用过程

JNI的对应代码在哪?

这部分主要是分析JNI的函数是如何生成的,不想了解的也可以直接跳过

注册binder

在Android系统开机过程中,Zygote启动时会有一个虚拟机注册过程,该过程调用 AndroidRuntime::startReg 方法来完成jni方法的注册(这部分分析来自gityuan)

在 AndroidRuntime.cpp 中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int AndroidRuntime::startReg(JNIEnv* env)
{
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

env->PushLocalFrame(200);
//注册 gRegJNI是一个数组,记录所有需要注册的jni方法,其中有一项是REG_JNI(register_android_os_Binder)
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);

return 0;
}

看看 register_android_os_Binder

1
2
3
4
5
6
7
8
9
10
11
12
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;
...
return 0;
}

看来需要一个一个看了

int_register_android_os_Binder 注册 Binder类的jni方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static int int_register_android_os_Binder(JNIEnv* env) {
//其中kBinderPathName = "android/os/Binder";查找kBinderPathName路径所属类
jclass clazz = FindClassOrDie(env, kBinderPathName);

//将Java层Binder类保存到mClass变量
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//将Java层execTransact()方法保存到mExecTransact变量;
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//将Java层mObject属性保存到mObject变量
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");

//注册JNI方法
return RegisterMethodsOrDie(env, kBinderPathName, gBinderMethods,
NELEM(gBinderMethods));
}

gBinderOffsets 是什么

1
2
3
4
5
6
7
static struct bindernative_offsets_t
{
jclass mClass; //记录Binder类
jmethodID mExecTransact; //记录execTransact()方法
jfieldID mObject; //记录mObject属性

} gBinderOffsets;

gBinderOffsets保存了Binder.java类本身以及其成员方法execTransact()和成员属性mObject,这为JNI层访问Java层提供通道。另外通过查询获取Java层 binder信息后保存到gBinderOffsets,而不再需要每次查找binder类信息的方式能大幅度提高效率,是由于每次查询需要花费较多的CPU时间,尤其是频繁访问时,但用额外的结构体来保存这些信息,是以空间换时间的方法

gBinderMethods

1
2
3
4
5
6
7
8
9
10
11
12
13
static const JNINativeMethod gBinderMethods[] = {
/* 名称, 签名, 函数指针 */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};

通过RegisterMethodsOrDie(),将为gBinderMethods数组中的方法建立了一一映射关系,从而为Java层访问JNI层提供通道

总之,int_register_android_os_Binder方法的主要功能:

  • 通过gBinderOffsets,保存Java层Binder类的信息,为JNI层访问Java层提供通道;
  • 通过RegisterMethodsOrDie,将gBinderMethods数组完成映射关系,从而为Java层访问JNI层提供通道。

注册BinderInternal

android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
 static int int_register_android_os_BinderInternal(JNIEnv* env) {
//其中kBinderInternalPathName = "com/android/internal/os/BinderInternal"
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");

return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

注册BinderInternal类的jni方法,gBinderInternalOffsets保存了BinderInternal的forceBinderGc()方法。

1
2
3
4
5
6
 static const JNINativeMethod gBinderInternalMethods[] = {
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
{ "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
{ "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};

注册BinderProxy

android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static int int_register_android_os_BinderProxy(JNIEnv* env) {
//gErrorOffsets保存了Error类信息
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

//gBinderProxyOffsets保存了BinderProxy类的信息
//其中kBinderProxyPathName = "android/os/BinderProxy"
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf", "Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");

//gClassOffsets保存了Class.getName()方法
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
1
2
3
4
5
6
7
8
9
10
static const JNINativeMethod gBinderProxyMethods[] = {
/* 名称, 签名, 函数指针 */
{"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},
};

这部分内容,读者只要清楚这些JNI对应的函数,系统会在运行开始之初帮你做好这些工作就行了

JNI的代码去哪找?

/frameworks/base/core/jni/

找到 android_util_Binder.cpp(JNI的命名一般是 包名路径_对应的JAVA函数名称)

1
2
3
4
5
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}

看到了熟悉的东西了没,ProcessState::self()就是前面在cpp代码时分析过的

1
2
3
4
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}

它的handle是0,0是什么,是service_manager,所以 ProcessState::self()->getContextObject(NULL) 返回的是一个 new BpBinder(0)

那么接下来再看看 javaObjectForIBinder 是个什么东西

1
2
3
4
5
6
7
8
9
10
11
12
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
......
//使用c代码调用NewObject来创建JAVA BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
//设置该对象的mObject = val.get = b = new BpBinder(0)
env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
......
}
return object;
}

因此 ServiceManagerNative.asInterface 等价于

ServiceManagerNative.asInterface(new BinderProxy())
其中 BinderProxy的mObject指向new BpBinder(0)

接下来看 asInterface

1
2
3
4
5
6
7
8
9
10
11
12
 static public IServiceManager asInterface(IBinder obj) {
//obj为BpBinder
if (obj == null) {
return null;
}
//由于obj为BpBinder,该方法默认返回null
IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);
}

因此 ServiceManagerNative.asInterface 等价于

new ServiceManagerProxy(new BinderProxy())

看看ServiceManagerProxy的构造函数

1
2
3
4
5
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}

mRemote为 BinderProxy 对象,该BinderProxy对象对应于BpBinder(0)
其作为binder代理端,指向native层的serviceManager

得知,getIServiceManager 就是获取一个 ServiceManagerProxy对象

既然它是一个BpBinder,在我们写cpp代码的时候,就应该知道它能干什么,注册服务获取服务等等

那么,framework层从 ServieManager的getService 开始,ServiceManagerProxy为自己的mRemote设置 BinderInternal.getContextObject() 从通过JNI方式返回的IBinder(指向service_manager)对象,后续通过 ServiceManagerProxy 来调用服务功能

获取到服务的binder后,下一步就是使用服务了

我们之前是这么用的

IHelloService svr = IHelloService.Stub.asInterface(binder);

现在去找到aidl生成的文件,找到 asInterface

1
2
3
4
5
6
7
8
9
10
11
12
// 根据 IBinder 构建一个 IHelloService 在android的源码中,这种使用方法非常常见
public static IHelloService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof IHelloService))) {
return ((IHelloService)iin);
}
return new IHelloService.Stub.Proxy(obj);
}

IHelloService.Stub.Proxy 是什么,也是aidl为我们生成的

1
2
3
4
5
6
7
//客户端的代理  是一个RPC过程,远程调用服务端的方法
private static class Proxy implements IHelloService{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote){
mRemote = remote;
}
}

这样就把Proxy中的mRemote赋值

然后就是调用服务中的方法了,之前我们的代码是svr.sayhello();

sayhello在Proxy中对应的函数方式代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public void sayhello() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}

那 mRemote.transact 是调用到哪里去?

mRemote 分析过他是一个 JAVA 中的 BinderProxy 对象(8.0被抽出来了,8.0的源码很多结构上都会有小小的变化,可能因为之前的代码的可读性确实比较差劲吧)

那么找到 BinderProxy 的 transact 函数

1
2
3
4
5
6
7
8
9
10
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
......
try {
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}

最终调用 transactNative ,又是native,那么我们就去源码里找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags)
{
...
//java Parcel转为native Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
Parcel* reply = parcelForJavaObject(env, replyObj);
...

//在前面的分析过程中我们设置了gBinderProxyOffsets.mObject为BpBinder,现在把这个BpBinder(0)取出来
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
...

//这个 target->transact 是 BpBinder::transact(),进入Binder驱动曾
status_t err = target->transact(code, *data, reply, flags);
...
return JNI_FALSE;
}

BpBinder::transact() 是不是很熟悉,cpp部分的源码,忘记的话回头看看cpp部分的分析,简单说下

  • BpBinder::transact()
  • IPCThreadState::self()->transact
  • writeTransactionData
  • waitForResponse
  • talkWithDriver
  • executeCommand

就是开个循环与server端进行通信,接受server端返回的数据

到此为止,client端就可以发送它的数据,这里是一个RPC远程调用过程,我们已经解决了第一个问题,client如何发送数据

接下来看第二个问题,Service是如何读取到数据,如何调用到onTransact函数的

回头看看AIDL为我们生成的代码

1
2
3
4
5
6
7
case TRANSACTION_sayhello:
{
data.enforceInterface(DESCRIPTOR);
this.sayhello();
reply.writeNoException();
return true;
}

在服务端是调用 this.sayhello()

这个this 是什么

1
2
3
4
@Override public android.os.IBinder asBinder()
{
return this;
}

可以得知他是一个IBinder,那么这个IBinder具体是指什么?

要分析server端的逻辑,就要从头开始了

我们编写server端的时候并没有自己写循环,那么他是怎么处理的?显然啊,肯定是系统自己处理了

在哪处理的?其实是使用app_process来启动server进程的过程中处理的

对于 AppRuntime 笔者不做过多分析,当然后续会有博文讲解

源码在 /frameworks/base/cmds/app_process/app_main.cpp 中

AppRuntime中有一个 onStarted() 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
virtual void onStarted()
{
sp<ProcessState> proc = ProcessState::self();
if (proc->supportsProcesses()) {
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
AndroidRuntime* ar = AndroidRuntime::getRuntime();
ar->callMain(mClassName, mClass, mArgC, mArgV);
if (ProcessState::self()->supportsProcesses()) {
IPCThreadState::self()->stopProcess();
}
}

注意到 proc->startThreadPool(),从名字应该能看出来,他是启动一个线程池

这个 proc 是一个 ProcessState

ProcessState 是什么还记得吗?

表示进程的一个结构体,在cpp部分做过分析

startThreadPool 总不能也忘了吧,忘了回头看看cpp的内部机制

  • proc->startThreadPool()
  • spawnPooledThread(true)
  • sp t = new PoolThread(isMain)
  • t->run(name.string())
  • IPCThreadState::self()->joinThreadPool(mIsMain)

在 joinThreadPool 中就开始循环处理请求了,根据命令处理,如果是 BR_TRANSACTION 就会根据cookie 转换为 BBinder,并调用他的 transact,BBinder的transact其实就等价于他的 onTransact

到此,我们解决了第二问题的一部分,也就是 server 是如何读取到数据

那么还剩最后一个问题,如何调用到onTransact函数的

既然BBinder的transact等价于他的 onTransact,那我们看看AIDL生成的文件中,他的 IBinder 实际对象是否为前面分析的 BBinder,如果是,整个流程就全通了

那就要从server端的开头开始分析了

server端流程

看看 addService 函数

1
2
3
4
5
6
7
8
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}

前面分析知道 getIServiceManager() 得到的是一个 ServiceManagerProxy ,找到他的 addService 函数

1
2
3
4
5
6
7
8
9
10
11
12
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);
// code 是 ADD_SERVICE_TRANSACTION
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}

重点在于 writeStrongBinder

writeStrongBinder

1
2
3
public writeStrongBinder(IBinder val){
nativewriteStrongBinder(mNativePtr, val);
}

又是一个native,去找找他对应的函数,在 android_os_Parcel.cpp 中

1
2
3
4
5
6
7
8
9
10
11
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) {
//将java层Parcel转换为native层Parcel
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// .cookie = ibinderForJavaObject(env, object)得到一个JavaBBinder对象
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}

看看 ibinderForJavaObject 是什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
//注意这个 obj 是传进来的 service 对象
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对象(new XXXService()) 转换为cpp IBinder对象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
return NULL;
}

看看 JavaBBinderHolder 的 get,他返回的是一个 JavaBBinder

1
2
3
4
5
6
7
8
9
10
sp<JavaBBinder> get(JNIEnv* env, jobject obj) {
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
// 这是一个wp类型的,可能会被垃圾回收器给回收,所以每次使用前,都需要先判断是否存在
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
}
return b;
}

看下 JavaBBinder 的构造函数

1
2
3
4
5
6
7
8
9
class JavaBBinder : public BBinder
{
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
}

他是一个 BBinder,越来越接近我们前面的猜想了

data.writeStrongBinder(service)最终等价于 parcel->writeStrongBinder(new JavaBBinder(env, obj));

obj = new XXXService() ,JavaBBinder的mObject = obj

parcel的writeStrongBinder是什么?

1
2
3
4
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}

看到 flatten_binder 应该熟悉了,根据IBinder构建 flat_binder_object ,并且把binder对象写道cookie里去,后续server才能通过cookie里去读取并使用

mRemote.transact

回到之前的调用,data.writeStrongBinder(service) 把数据进行一个转换并放入data后

调用

mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)

还记得这个mRmote是什么吗

我们分析 IServiceManager 的时候

1
2
3
4
5
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}

mRemote为 BinderProxy 对象,该 BinderProxy 对象对应于BpBinder(0)

那么找到 BinderProxy 的 transact 函数,其实前面已经分析过这部分了

1
2
3
4
5
6
7
8
9
10
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
......
try {
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}

最终调用 transactNative ,又是native,那么我们就去源码里找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags)
{
...
//java Parcel转为native Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
Parcel* reply = parcelForJavaObject(env, replyObj);
...

//在前面的分析过程中我们设置了gBinderProxyOffsets.mObject为BpBinder,现在把这个BpBinder(0)取出来
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
...

//这个 target->transact 是 BpBinder::transact(),进入Binder驱动曾
status_t err = target->transact(code, *data, reply, flags);
...
return JNI_FALSE;
}

BpBinder::transact() cpp部分的源码

  • BpBinder::transact()
  • IPCThreadState::self()->transact
  • writeTransactionData
  • waitForResponse
  • talkWithDriver
  • executeCommand

开个循环与server端进行通信,接受server端返回的数据,这里我们的client端是server,server端是service_manager

总结注册服务流程

  • new XXXService()
  • data.writeStrongBinder(service)
  • JNI调用
  • service JAVA对象 转换为 JAVABBinder cpp对象
  • 将 JAVABBinder 给 cookie
  • 调用 BinderProxy 的 transact
  • BpBinder::transact()
  • 与驱动进行通信
  • 驱动接收数据,完成服务的注册工作

到此为止,我们只是分析了他如何注册服务的,还没得到我们第三个问题的答案

之前分析过,系统会帮我们创建一个循环来担任server端的循环处理工作,那么在循环过程中,会去读取客户端发送过来的消息,在分析cpp的代码时,会在接收到数据后,取出 cookie 转换为 BBinder,并调用BBinder派生类的onTransact函数,我们注册服务的时候,BBinder的派生类是 JAVABBinder ,因此我们只需要去找 JAVABBinder 的 onTransact 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int strict_policy_before = thread_state->getStrictModePolicy();
thread_state->setLastTransactionBinderFlags(flags);
//调用JAVA中的某个函数
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, (int32_t)&data, (int32_t)reply, flags);
jthrowable excep = env->ExceptionOccurred();
......
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}

看 CallBooleanMethod 它到底调用的是JAVA里的哪个函数

1
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

mObject指向 XXXService对象
gBinderOffsets.mExecTransact指向: android/os/Binder类中的 execTransact 方法
那么上面的 CallBooleanMethod 就是调用XXXService(派生自Binder)对象中的execTransact方法

那么查找 execTransact,它是在AIDL为我们生成的文件中,Stub的父类,Binder里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
BinderCallsStats binderCallsStats = BinderCallsStats.getInstance();
BinderCallsStats.CallSession callSession = binderCallsStats.callStarted(this, code);
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
boolean res;
final boolean tracingEnabled = Binder.isTracingEnabled();
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
......
} finally {
......
}
......
return res;
}

可以发现,它调用的是 onTransact 函数,这个onTransact就是它的子类实现的 onTransact,它的子类就是AIDL为我们生成的 Stub 中,在我们之前写的测试代码中是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_sayhello:
{
data.enforceInterface(DESCRIPTOR);
this.sayhello();
reply.writeNoException();
return true;
}
case TRANSACTION_sayhello_to:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
int _result = this.sayhello_to(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

至此,我们已经知道第三个问题的答案了,知道它是如何调用到JAVA层的onTransact函数

笔者完善了开头的图