android10Binder(五)java世界的binder:AndroidFramework
阅读原文时间:2023年07月08日阅读:3

java世界的binder:AndroidFramework

目录

我们阅读分析了native的binder使用案例,覆盖了大多数情景,总结出一套标准的binder机制使用动作。

进程启动后要使用ProcessState操作binder驱动:open与mmap。之后新建线程池和加线程startThreadPool和joinThreadPool,进入waitResponse-->talkWithDriver的死循环,不断地同binder驱动进行ioctl,读操作。这是一个服务端的binder线程要做的工作,就是不断的读驱动然后处理返回数据。

而发起者进程,在发起binder-ipc时,但前线程也是死循环吗?不是的,不同点在waitForResponse方法里,当发起者transact方法发起ipc,正常情况,之后要么收到BR_REPLY表示一个来回的完成,要么是oneway的BR_TRANSACTION_COMPLETE。当然还有其他情况,这几种情况都会goto finish将循环退出,这样就返回到remote()->transact的调用处,下一步就可以处理reply这个返回的parcel数据包了。

简单的两段话,是否让你对native的binder使用流程有了形象的概念,读代码的目的就是将死的文本变成脑海里,动态的,对象之间情景交互,数据的流动。

native我们总结完了,再来思考java世界。

如果给你这个需求,让你设计实现一个java世界的binder使用机制,你会怎么设计?重点有2。

一个是进程的接收能力。每个进程初始化是也要open,mmap以及创建binder线程不断地读驱动。并且线程接收到客户请求之后,也可以走到类似Bnxxx类里的onTransact回调,这样走到真正的实现,然后sendReply。

另一个呢,就是一个进程的发送能力。在发起ipc的时候,也要同native一样,有一个库文件给我们客户端用,类似BpxxxService,直接调用它的接口即可。

完成了这俩功能,思考一下,我们作为普通的app进程就可以给系统服务ipc发消息,然后可以收到答复了

同样的,例如系统服务AMS,可以给别的系统服务ipc发消息收消息,也可以收app进程的请求然后给他答复。

另外,考虑到代码复用,我们最好直接jni调用native现成的接口,也就是libbinder工具库里的接口。

上面我们这些简单的畅想,正是目前aosp里的实现。也就是说,java的binder框架是native框架的映射。(匿名binder后续讨论,也就是app与app进程的binder通信,我们常用的bindeService)

现在就让我们看看SystemServer进程启动时的open,mmap动作和AMS系统服务的注册动作。

system_server进程怎么启动的可以参考Android 10.0 系统启动之SystemServer进程-[Android取经之路]

其实你应该知道,所有java进程的启动流程都是如此,不管是app进程还是系统服务进程又或者是我们调试用的cmd命令所在的进程,都是通过app_process也就是zygote进程fork出来的子进程。fork完后都会走到ZygoteInit.java的zygoteInit-->nativeZygoteInit,然后跳到native里,在app_main.cpp的onZygoteInit方法里完成我们的第一个需求,open,mmap和建立线程、线程池、死循环读驱动。

frameworks/base/cmds/app_process/app_main.cpp

 92     virtual void onZygoteInit()
 93     {
 94         sp<ProcessState> proc = ProcessState::self();
 95         ALOGV("App process: starting thread pool.\n");
 96         proc->startThreadPool();
 97     }

又是你,ProcessState。我们见过他最最起码3次了,sm启动(Android11上的)、sf启动、bootanimation启动,加上这次是第四次。

如果你有心可以再去其他的native程序里找找,例如dumpstate啊,vold啊,mediaServer啊等等,都会看到他们的main里调用ProcessState来完成本进程的binder初始化工作。看多了你就有很直白的印象,哦,原来大家用binder的第一步就是ProcessState::self()startThreadPool

system_server进程是一个java世界的进程,是由zygote孵化出来的进程。不止system_server,所有的java进程都是由zygote孵化出来的。所以明显的,我们答案找到了。

system_server进程(或者APP进程),是怎么完成open binder驱动,mmap等等初始化操作的?

答案:还是通过libbinder库的ProcessState类。流程是在zygote fork子进程之后native 的onZygoteInit方法里。

一些前置

native进程是如何注册自己到sm的?

我想你一定很清楚了,就是使用libbinder库的接口,先defaultServiceManager拿到一个BpServiceManager对象,然后调用它的addService方法,talkwithdriver。通过binder驱动将自己的服务解析为binder_ref和handle,sm记下来保存在svclist里。

那么现在我们带着问题去看代码,java进程里如何注册自己到sm?

不赘述工具辅助类SystemServiceManager的startService流程,注册的地方。

frameworks/base/services/java/com/android/server/SystemServer.java

 623     private void startBootstrapServices() {
 777         // Set up the Application instance for the system process and get started.
 779         mActivityManagerService.setSystemProcess();

meworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 2040     public void setSystemProcess() {
 2041         try {
 2042             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
 2043                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
//------------------------------------------------------------------------------
 2044             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
 2045             ServiceManager.addService("meminfo", new MemBinder(this)
 2047             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
 2048             ServiceManager.addService("dbinfo", new DbBinder(this));
 2050                 ServiceManager.addService("cpuinfo", new CpuBinder(this),

2042行是ams的注册,下面几个是其他服务的注册什么内存啊cpu啊。由于都和ams有强联系,所以在这里初始化和注册。

2042行跳转。会发现我们跳到了一个ServiceManager.java的类里。frameworks/base/core/java/android/os/ServiceManager.java

还记得native是通过啥addService吗?我们需要在mk里依赖libbinder这个so,然后#include <binder/IServiceManager.h>

现在是java世界了,有什么不同吗?

套路上是完全一致的。ServiceManager.java这个类我们在ams里有import。261 import android.os.ServiceManager;

并且也有在编译时依赖一个库,只不过这个库是jar包,且是zygote帮我们preloadclass阶段预加载好的。默认就能用,不需要在java程序的mk里面显式添加依赖。native的libbinder需要显式添加依赖。

frameworks/base/Android.bp

  28 java_defaults {
  29     name: "framework-defaults",
  30     installable: true,
  32     srcs: [
  34         "core/java/**/*.java",
  77         "core/java/android/app/ISearchManager.aidl",
  78         "core/java/android/app/ISearchManagerCallback.aidl",
//----------------------------------------------------------------------------------
 825 java_library {
 826     name: "framework",
 827     defaults: ["framework-defaults"],
 828     javac_shard_size: 150,
 829 }

现在走进ServiceManager.java#addService

frameworks/base/core/java/android/os/ServiceManager.java

178     /**
179      * Place a new @a service called @a name into the service
180      * manager.
181      *
182      * @param name the name of the new service
183      * @param service the service object
184      * @param allowIsolated set to true to allow isolated sandboxed processes
185      * @param dumpPriority supported dump priority levels as a bitmask
186      * to access this service
187      */
188     @UnsupportedAppUsage
189     public static void addService(String name, IBinder service, boolean allowIsolated,
190             int dumpPriority) {
191         try {
192             getIServiceManager().addService(name, service, allowIsolated, dumpPriority);

研究一下入参。

  • name是Context.ACTIVITY_SERVICE

frameworks/base/core/java/android/content/Context.java

3535     public static final String ACTIVITY_SERVICE = "activity";
  • service是this,也就是ams对象自己,ams是个Binder对象。

    //frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    401 public class ActivityManagerService extends IActivityManager.Stub
    402 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    //out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/android/app/IActivityManager.java
    11 public interface IActivityManager extends android.os.IInterface
    12 {
    871 /** Local-side IPC implementation stub class. */
    872 public static abstract class Stub extends android.os.Binder implements android.app.IActivityManager
    //frameworks/base/core/java/android/os/Binder.java
    75 public class Binder implements IBinder {

后俩参数不管了。看getIServiceManager方法的实现。

frameworks/base/core/java/android/os/ServiceManager.java

105     private static IServiceManager getIServiceManager() {
106         if (sServiceManager != null) {
107             return sServiceManager;
108         }
110         // Find the service manager
111         sServiceManager = ServiceManagerNative
112                 .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
113         return sServiceManager;
114     }

asinterface,眼熟吗?native那个花里胡哨的宏还是模板,在那个方法里会new一个BpxxxService对象,例如BpServiceManager(new BpBinder(0))、BpSurfaceComposer(new BpBinder(handle))。这里也是类似。

 28 public abstract class ServiceManagerNative extends Binder implements IServiceManager
 29 {
 35     static public IServiceManager asInterface(IBinder obj){
 46         return new ServiceManagerProxy(obj);
 47     }

看,是不是和native里长的很像,只不过Bpxxx变成了xxxProxy而已。我们再看看obj这个参数怎么来的。

Binder.allowBlocking(BinderInternal.getContextObject())

frameworks/base/core/java/com/android/internal/os/BinderInternal.java

156     /**
157      * Return the global "context object" of the system.  This is usually
158      * an implementation of IServiceManager, which you can use to find
159      * other services.
160      */
161     @UnsupportedAppUsage
162     public static final native IBinder getContextObject();

一看到jni调用猜也能猜到,又是去偷native的ServiceManager实例了。

frameworks/base/core/jni/android_util_Binder.cpp

1033 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) {
1035     sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
1036     return javaObjectForIBinder(env, b);

1035行又是老熟人,再回顾一下。

frameworks/native/libs/binder/ProcessState.cpp

116 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
117 {
118     return getStrongProxyForHandle(0);
119 }
259 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){
300             b = BpBinder::create(handle);
303             result = b;
313     return result;

native拿到的还是那个BpBinder(0)对象。这里300行是第一次初始化的,单例。之后请求都是存好的,此处为了好说明所以又把create这一行贴出来。

1036行是新东西

frameworks/base/core/jni/android_util_Binder.cpp

 662 // If the argument is a JavaBBinder, return the Java object that was used to create it.
 663 // Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
 664 // same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
 665 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val){

简单说一下,就是返回一个BinderProxy对象。BinderProxy关联了native的sm BpBinder对象,放在BinderProxy.mObject成员变量里。native怎么创造出java对象,是通过反向jni,可以自行阅读。

现在,问题的答案浮出水面,返回返回返回到最初的IServiceManager getIServiceManager()方法。

这个方法的返回值就是return new ServiceManagerProxy(new BinderProxy());

还是和native的十分的像,native是new BpServiceManager(new BpBinder())

接着看下一步addService方法。

frameworks/base/core/java/android/os/ServiceManagerNative.java

113 class ServiceManagerProxy implements IServiceManager {
114     public ServiceManagerProxy(IBinder remote) {
115         mRemote = remote;
147     public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
148             throws RemoteException {
149         Parcel data = Parcel.obtain();
150         Parcel reply = Parcel.obtain();
151         data.writeInterfaceToken(IServiceManager.descriptor);
152         data.writeString(name);
153         data.writeStrongBinder(service);
154         data.writeInt(allowIsolated ? 1 : 0);
155         data.writeInt(dumpPriority);
156         mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
157         reply.recycle();
158         data.recycle();
159     }

look,是不是又很眼熟,简直是native的翻版。而且java的代码好读的多,之前我们native的remote()找了半天,现在不用找了,直接给你放旁边

151-155行,java的Parcel啥也没做直接jni调native Parcel.cpp里的实现。

然后156行也是BinderProxy跳到native的BpBinder里用他的transact方法,我们之前分析过,就是IPCThhreadStated里talkwithdriver那套流程。然后返回值也是放在reply这个parcel对象里。

3.1 Parcel:java是对native的封装

看一下writeStrongBinder,比较重要

frameworks/base/core/java/android/os/Parcel.java

 786     public final void writeStrongBinder(IBinder val) {
 787         nativeWriteStrongBinder(mNativePtr, val);
 788     }

frameworks/base/core/jni/android_os_Parcel.cpp

298 static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object){
300     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
302         const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));

看302行,和native不同之处是这里的传参不是服务实体对象,我们进去看一下ibinderForJavaObject。

3.2 ibinderForJavaObject:BinderProxy到BpBinder的映射

frameworks/base/core/jni/android_util_Binder.cpp

 706 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) {
 710     // Instance of Binder?
 711     if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
 712         JavaBBinderHolder* jbh = (JavaBBinderHolder*)
 713             env->GetLongField(obj, gBinderOffsets.mObject);
 714         return jbh->get(env, obj);
 715     }
 716
 717     // Instance of BinderProxy?
 718     if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
 719         return getBPNativeData(env, obj)->mObject;
 720     }
 724 }

当传入的obj是java里Binder对象就走711行,是BinderProxy就走718行。由于我们传下来的是AMS,又AMS 继承IActivityManager.Stub,Stub又继承android.os.Binder。所以我们走711行分支。

AMS有成员变量mObject吗?有,在父类Binder.java里

 249 //Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
 252     private final long mObject;

这个对象在何时赋值的?在Binder.java构造函数里,在AMS实例化时,走了父类的构造函数

frameworks/base/core/java/android/os/Binder.java

 559     public Binder(@Nullable String descriptor)  {
 560         mObject = getNativeBBinderHolder();
 561         NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
 571         mDescriptor = descriptor;
 572     }

frameworks/base/core/jni/android_util_Binder.cpp

 937 static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
 938 {
 939     JavaBBinderHolder* jbh = new JavaBBinderHolder();
 940     return (jlong) jbh;
 941 }
 418 // ----------------------------------------------------------------------------
 420 class JavaBBinderHolder {
 422 public:
 423     sp<JavaBBinder> get(JNIEnv* env, jobject obj){
 425         AutoMutex _l(mLock);
 426         sp<JavaBBinder> b = mBinder.promote();
 427         if (b == NULL) {
 428             b = new JavaBBinder(env, obj);
 429             mBinder = b;
 432         }
 434         return b;
 435     }
 443 private:
 445     wp<JavaBBinder> mBinder;
 446 };

所以560行拿到的mObject代表native的JavaBBinderHolder对象。561行registerNativeAllocation是gc相关,可以参考:

Android | 带你理解 NativeAllocationRegistry 的原理与设计思想

ART视角 | 如何让GC同步回收native内存

回到ibinderForJavaObject方法714行的get调用,跳转到JavaBBinderHolder类get方法。423-434行。我们可以看到,get方法里new了一个JavaBBinder实例。看下这个类

 301 class JavaBBinder : public BBinder
 302 {
 303 public:
 304     JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
 305         : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)) {}
 410 private:
 411     JavaVM* const   mVM;
 412     jobject const   mObject;  // GlobalRef to Java Binder

可以看到,构造函数中将java的ams对象拿到了native也存了一份到mObject。

现在要梳理一下java和native这三个对象的关系了。java对象继承了android.os.Binder.java,native的俩对象是JavaBBinderHolder和JavaBBinder

java对象,持有的mObject,是JavaBBinderHolder

JavaBBinderHolder持有的mBinder是JavaBBinder

JavaBBinder持有的mObject是java对象

3.3 BinderProxy.transact是对BpBinder::transact的封装

frameworks/base/core/java/android/os/BinderProxy.java

473     public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
509         try {
510             return transactNative(code, data, reply, flags);

frameworks/base/core/jni/android_util_Binder.cpp

1279 static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1280         jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1281 {
1296     IBinder* target = getBPNativeData(env, obj)->mObject.get();
1318     //printf("Transact from Java code to %p sending: ", target); data->print();
1319     status_t err = target->transact(code, *data, reply, flags);

1296行拿出我们BinderProxy之前存好的native的BpBinder对象,然后通过这个BpBinder走入native的binder ipc流程。

之后流程就是之前文章分析的那样,不再赘述。

addService之后,java的SM也就相当于保存了这个新注册的服务,因为java的SM只是native的封装,通过jni调用而已。

4.1 App-->driver

现在分析这样的场景,app进程想使用AMS服务的功能,例如这个接口getCurrentUser。我们假设app进程已经创建,现在处于app的Activity环境里。(这里隐藏的含义就是APP进程已经历了zygoteInit流程里ProcessState的open、mmap、建立binder线程等初始化)

…/MainActivity.java

1 package com.example.app;
2 import android.app.ActivityManager;
3 public class MainActivity extends Activity {
4     @Override
5     protected void onResume() {
6         super.onResume();
7         int currentUserId = ActivityManager.getCurrentUser();
8         Log.d(TAG,"getCurrentUser : " + currentUserId);

走进第7行。

frameworks/base/core/java/android/app/ActivityManager.java

3825     public static int getCurrentUser() {
3826         UserInfo ui;
3827         try {
3828             ui = getService().getCurrentUser();
3829             return ui != null ? ui.id : 0;

看3828行的getService方法。

frameworks/base/core/java/android/app/ActivityManager.java

4041     public static IActivityManager getService() {
4042         return IActivityManagerSingleton.get();}
//--------------------------------------------------------------------------
4050     private static final Singleton<IActivityManager> IActivityManagerSingleton =
4051             new Singleton<IActivityManager>() {
4052                 @Override
4053                 protected IActivityManager create() {
4054                     final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
4055                     final IActivityManager am = IActivityManager.Stub.asInterface(b);
4056                     return am;
4057                 }
4058             };

frameworks/base/core/java/android/util/Singleton.java

 28 public abstract class Singleton<T> {
 35     public final T get() {
 36         synchronized (this) {
 37             if (mInstance == null) {
 38                 mInstance = create();
 39             }
 40             return mInstance;

可以看到getService其实拿到的是一个4055行的IActivityManager类型的对象Stub.Proxy(BinderProxy),单例模式,每个进程只有一个。

4054行的IBinder对象如何获取的就不说了,同之前的ServiceManager.addService流程一样。走下去你会发现还是调用这样一句话。

frameworks/base/core/java/android/os/ServiceManager.java

260     private static IBinder rawGetService(String name) throws RemoteException {
263         final IBinder binder = getIServiceManager().getService(name);

现在我们看下4055行的实现。

out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/androi

d/app/IActivityManager.java

 872   public static abstract class Stub extends android.os.Binder implements android.app.IActivityManager
 873   {
 884     public static android.app.IActivityManager asInterface(android.os.IBinder obj)
 885     {
 893       return new android.app.IActivityManager.Stub.Proxy(obj);
 894     }
4504     private static class Proxy implements android.app.IActivityManager
4505     {
4506       private android.os.IBinder mRemote;
4507       Proxy(android.os.IBinder remote)
4508       {
4509         mRemote = remote;
4510       }

可以看到。Proxy是Stub的子类,所以最终返回的对象是return new android.app.IActivityManager.Stub.Proxy(new BinderProxy());现在回到4055行、3828行。3828行的getService().getCurrentUser()就是调用这个Stub.Proxy类的getCurrentUser方法

out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/androi

d/app/IActivityManager.java

7288       @Override public android.content.pm.UserInfo getCurrentUser() throws android.os.RemoteException
7289       {
7290         android.os.Parcel _data = android.os.Parcel.obtain();
7291         android.os.Parcel _reply = android.os.Parcel.obtain();
7292         android.content.pm.UserInfo _result;
7293         try {
7294           _data.writeInterfaceToken(DESCRIPTOR);
7295           boolean _status = mRemote.transact(Stub.TRANSACTION_getCurrentUser, _data, _reply, 0);
7296           if (!_status && getDefaultImpl() != null) {
7297             return getDefaultImpl().getCurrentUser();
7298           }
7299           _reply.readException();
7300           if ((0!=_reply.readInt())) {
7301             _result = android.content.pm.UserInfo.CREATOR.createFromParcel(_reply);
7302           }
7303           else {
7304             _result = null;
7305           }
7306         }
7307         finally {
7308           _reply.recycle();
7309           _data.recycle();
7310         }
7311         return _result;
7312       }

又是眼熟的这样一套写法,7292行准备parcel对象,7294行写进请求数据,7295行借助BinderProxy开始跨进程调用,返回值在入参_reply,7301行将返回数据解包拿出来,7308行清理垃圾。

4.2 driver-->AMS

我们跳过冗杂的binder驱动处理流程,直接跳转到system_server进程中AMS处理这次binder请求的线程。现在它从talkwithdriver中苏醒,返回上层的waitForResponse,然后executecommand,解析cmd是case BR_TRANSACTION。

最后又走到了1213行,

frameworks/native/libs/binder/IPCThreadState.cpp

1208             if (tr.target.ptr) {
1213                     error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
1214                             &reply, tr.flags);

还是我们之前分析的,tr.cookie是代表服务端的BBinder对象,继续走

frameworks/native/libs/binder/Binder.cpp

123 status_t BBinder::transact(
124     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
129     switch (code) {
133         default:
134             err = onTransact(code, data, reply, flags);
135             break;

这里发生了不同的变化,我们的134行onTransact走向了何方?答案是BBinder的实现类,android_util_Binder.cpp文件class JavaBBinder。

frameworks/base/core/jni/android_util_Binder.cpp

301 class JavaBBinder : public BBinder
 302 {
 355     status_t onTransact(
 356         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
 357     {
 358         JNIEnv* env = javavm_to_jnienv(mVM);
 368         jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
 369             code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

368行反向jni调用java的mObiect类里方法"execTransact"。mObject是AMS对象,上一节有分析。

 996     gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");

现在让我们跳到AMS的java世界,现在处于Binder.java类里

frameworks/base/core/java/android/os/Binder.java

 987     private boolean execTransact(int code, long dataObj, long replyObj,
 988             int flags) {
 993         try {
 994             return execTransactInternal(code, dataObj, replyObj, flags, callingUid);
//---------------------------------------------------------------
1000     private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags,
1001             int callingUid) {
1021             res = onTransact(code, data, reply, flags);

继续,由于派生类实现了这个onTransact方法,所以现在跳转到Binder.java的子类,IActivityManager.Stub类

out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/androi

d/app/IActivityManager.java

 734     protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
 735             int flags) throws RemoteException {
1703     @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
1704     {
1705       java.lang.String descriptor = DESCRIPTOR;
1706       switch (code)
1707       {
3436         case TRANSACTION_getCurrentUser:
3437         {
3438           data.enforceInterface(descriptor);
3439           android.content.pm.UserInfo _result = this.getCurrentUser();
3440           reply.writeNoException();
3441           if ((_result!=null)) {
3442             reply.writeInt(1);
3443             _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
3444           }
3445           else {
3446             reply.writeInt(0);
3447           }
3448           return true;
3449         }

还记得很久很久以前,我们的APP进程发起mRemote.trancact时传的cmd,是啥吗?

正是TRANSACTION_getCurrentUser。所以现在服务端AMS就switch到这里。

3439行的this是谁?你可别说是Stub对象。要分的清,当前是没有Stub对象的,有的只是AMS,这个Stub里的方法是AMS继承来的,而不是实例化的Stub。

所以跳转到AMS的getCurrentUser。具体怎么实现的我们就不管了了,总之我们拿到了AMS方法处理好的数据,现在开始返回。

3443将数据写进parcel

frameworks/base/core/java/android/content/pm/UserInfo.java

275     public void writeToParcel(Parcel dest, int parcelableFlags) {
276         dest.writeInt(id);
277         dest.writeString(name);
278         dest.writeString(iconPath);
279         dest.writeInt(flags);
280         dest.writeInt(serialNumber);
281         dest.writeLong(creationTime);
282         dest.writeLong(lastLoggedInTime);
283         dest.writeString(lastLoggedInFingerprint);
284         dest.writeInt(partial ? 1 : 0);
285         dest.writeInt(profileGroupId);
286         dest.writeInt(guestToRemove ? 1 : 0);
287         dest.writeInt(restrictedProfileParentId);
288         dest.writeInt(profileBadge);
289     }

是不是解决了你长久以来的一个疑问,读了这么久框架代码,这个writeToParcel啥时候用的?就是在这里用的,工具函数,不用一行一行写了。

4.3 AMS---sendReply--->driver--->App

现在回到了4.2小节的开头,IPCThreadState.cpp的executeCommand方法里。

1068 status_t IPCThreadState::executeCommand(int32_t cmd){
1074     switch ((uint32_t)cmd) {
1148     case BR_TRANSACTION:{
1208             if (tr.target.ptr) {
1211                 if (reinterpret_cast<RefBase::weakref_type*>(
1212                         tr.target.ptr)->attemptIncStrong(this)) {
1213                     error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
1214                             &reply, tr.flags);
1216             }
1228             if ((tr.flags & TF_ONE_WAY) == 0) {
1229                 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
1230                 if (error < NO_ERROR) reply.setError(error);
1231                 sendReply(reply, 0);
1232             } else {
1233                 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);

服务端的服务数据计算完毕,从1213行走下来。由于我们APP进程发起时未指定oneway,所以是走到1231行的sendReply,参数reply就是刚才填充的服务数据,我们的currentUserId。之前分析过这个方法,此处不再展开。

略过驱动的又一次数据流转,回到App进程用户空间,也是回到IPCThreadState的waitForResponse里,拿到数据判断是BR_REPLY退出死循环,然后就返回到梦开始的地方。IActivityManager.java第7295行。

out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/androi

d/app/IActivityManager.java

7288       @Override public android.content.pm.UserInfo getCurrentUser() throws android.os.RemoteException
7289       {
7293         try {
7294           _data.writeInterfaceToken(DESCRIPTOR);
7295           boolean _status = mRemote.transact(Stub.TRANSACTION_getCurrentUser, _data, _reply, 0);
7300           if ((0!=_reply.readInt())) {
7301             _result = android.content.pm.UserInfo.CREATOR.createFromParcel(_reply);
7302           }
7306         }
7311         return _result;
7312       }

我们的transact调用终于tm的结束了,这篇文章我写了一天了,从上午9点写到晚上9点45,太累了。中午没午休,晚饭也没吃,加油写完回家吃饭躺平。

现在走到7301行将AMS返回的数据解包,7311再次返回上层,一直一直一直返回到app的MainActivity第7行,然后第8行就将数据打印出来liao。

java世界的增,查,正向调用流程,逆向返回流程我们都走了一遍,大功告成。回家吃饭