目录
我们阅读分析了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);
研究一下入参。
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对象里。
看一下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。
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 的原理与设计思想
回到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对象
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调用而已。
现在分析这样的场景,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行清理垃圾。
我们跳过冗杂的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.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世界的增,查,正向调用流程,逆向返回流程我们都走了一遍,大功告成。回家吃饭
手机扫一扫
移动阅读更方便
你可能感兴趣的文章