--- title: 'Binder - Java Binder 原理' disqus: kyleAlien --- Binder - Java Binder 原理 === ## OverView of Content Java Binder 是建構在 Native Binder 之上,同樣是 Client/Server 架構 [TOC] ## Java & JNI - Binder * Java 類 Binder 介紹 | Java 類 | 對應 Native 類 | 其他 | | - | - | - | | [**IBinder**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/IBinder.java) | IBinder.h | 重點提供 java 層 `transact` 方法 | | [**IInterface**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/IInterface.java) | IInterface.h | 與 IBinder 產生關係 | | [**Binder**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Binder.java) | BBinder.h | 所有 Java Service 都繼承於 Binder,同樣複寫 `transact` 方法,並把實際業務反應到 `onTransact` 方法,包裝了 JNI 實現 | | [**BinderProxy**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/BinderProxy.java) | BpBinder | Client 端訪問 Server 時使用的代理,包裝了 JNI 實現 | * JNI 類 Binder 介紹 | JNI | 功能說明 | | - | - | | [**JavaBBinderHolder**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp) | 包裝 JavaBBinder,延遲加載 JavaBBinder | | [**JavaBBinder**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp) | 將 BBinder 的 `onTransact` 調用到 Java 端(Binder.java) | | [**Parcel**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Parcel.java) | 銜接 java & cpp 端 | > ![](https://i.imgur.com/3fdPyCm.png) ## JNI 註冊時機 由於 Java Binder 是建構在 Native Binder 之上,所以 Java 要跟 Native 通訊時,必須要透過 JNI 通訊 JNI 的註冊是在 Zygote 進程啟動中註冊的,請參考 [**Android Runtime**](https://hackmd.io/SKv3cRkNTl66owHVhVG8Ow?view#%E5%95%9F%E5%8B%95%E8%99%9B%E6%93%AC%E6%A9%9F---AndroidRuntimestart) ### Java Binder - [JNI 註冊](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/AndroidRuntime.cpp) * [**AndroidRuntime#startReg**](https://hackmd.io/SKv3cRkNTl66owHVhVG8Ow?view#AndroidRuntime---startReg) 會註冊所有的 JNI,其中也就包括了 Java Binder 的 JNI ```java= static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env) { for (size_t i = 0; i < count; i++) { if (array[i].mProc(env) < 0) { ... 註冊失敗訊息 return -1; } } return 0; } static const RegJNIRec gRegJNI[] = { ... 省略其他 JNI 函數指針 // @ register_android_os_Binder REG_JNI(register_android_os_Binder), } ``` * 調用函數指針其實就是呼叫 symbol 為 `register_android_os_Binder` 的函數,該函數定義在 [**android_util_Binder.cpp**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp),在這裡我們先了解 Binder 在 Java 的重點類別 | Java 類 | 功能 | 其他 | | - | - | - | | IBinder.java | 定義許多 int 變數 | 一般發起 Binder 通訊都會 Block 調用 Thread 直到返回,如果設定 `FLAG_ONEWAY` 就不會堵塞 | | Binder.java | 代表 **服務端** | 就像是 BBinder | | BinderProxy.java | 代表 **客戶端** | 就像是 BpBinder | | BinderInternal.java | 在 **服務端框架中使用**,可以用它取得 Binder 代理類 | 內部類 GcWatcher 用於處理 Binder 垃圾回收 | | Parcel.java | 可傳送基礎數據,也可以 **傳送對象**,是 Binder 通訊的基礎 | 具體時現在 [**Native Parcel**](https://hackmd.io/Qr4dm2XsSpyhMeB5dIePyA?vie) | ```cpp= // android_util_Binder.cpp int register_android_os_Binder(JNIEnv* env) { // 註冊 Binder 類 // @ int_register_android_os_Binder if (int_register_android_os_Binder(env) < 0) return -1; // 註冊 BinderInternal 類 // @ int_register_android_os_BinderInternal if (int_register_android_os_BinderInternal(env) < 0) return -1; // 註冊 BinderProxy 類 // @ int_register_android_os_BinderProxy if (int_register_android_os_BinderProxy(env) < 0) return -1; ... 省略部份 return 0; } ``` > ![](https://i.imgur.com/EupWK1m.png) ### JNI 註冊 - [Binder 類](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Binder.java) * 在上面我們了解到 **AndroidRuntime 會註冊所有的 JNI 方法**,其中就包括 Binder JNI (`register_android_os_Binder`),現在我們來分析其中的 `register_android_os_Binder` 方法 ```cpp= // android_util_Binder.cpp const char* const kBinderPathName = "android/os/Binder"; static int int_register_android_os_Binder(JNIEnv* env) { // 1. 取得 Binder class jclass clazz = FindClassOrDie(env, kBinderPathName); // 2. 將常用的類、方法、段 轉為全域 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"); // 3. 註冊 gBinderMethods 陣列中的所有方法 return RegisterMethodsOrDie( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); } ``` 1. `kBinderPathName` 數值是 `android/os/Binder`,Binder 在 Java Binder 中的 **全路徑名**,在 JNI 層需要獲取其 **類對象 (jclass)** 2. 透過 MakeGlobalxxx 方法,將 **全域參數** `gBinderOffsets` 的 mClass、jmethodID、jfieldID 賦值 | JNI 全域儲存 | Java 對應 | | -------- | -------- | | mClass | Binder 的 class 對象 | | mExecTransact | Binder#execTransact 方法 | | mGetInterfaceDescriptor | Binder#getInterfaceDescriptor 方法 | | mObject | Binder#mObject 成員 | ```cpp= // android_util_Binder.cpp static struct bindernative_offsets_t { // Class state. jclass mClass; jmethodID mExecTransact; jmethodID mGetInterfaceDescriptor; // Object state. jfieldID mObject; } gBinderOffsets; ``` :::info * 存為全域方法、段 可以方便之後使用,不用每次都去獲取 ::: 3. 註冊 與 JNI 相對應的 Java 參數 ```cpp= // android_util_Binder.cpp static const JNINativeMethod gBinderMethods[] = { /* name, signature, funcPtr */ // @CriticalNative { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid }, // @CriticalNative { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid }, // @CriticalNative { "isDirectlyHandlingTransaction", "()Z", (void*)android_os_Binder_isDirectlyHandlingTransaction }, // @CriticalNative { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity }, // @CriticalNative { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity }, // @CriticalNative { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy }, // @CriticalNative { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy }, // @CriticalNative { "setCallingWorkSourceUid", "(I)J", (void*)android_os_Binder_setCallingWorkSourceUid }, // @CriticalNative { "getCallingWorkSourceUid", "()I", (void*)android_os_Binder_getCallingWorkSourceUid }, // @CriticalNative { "clearCallingWorkSource", "()J", (void*)android_os_Binder_clearCallingWorkSource }, { "restoreCallingWorkSource", "(J)V", (void*)android_os_Binder_restoreCallingWorkSource }, { "markVintfStability", "()V", (void*)android_os_Binder_markVintfStability}, { "forceDowngradeToSystemStability", "()V", (void*)android_os_Binder_forceDowngradeToSystemStability}, { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder }, { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer }, { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }, { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension }, { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension }, }; ``` ### JNI 註冊 - [BinderInternal 類](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/com/android/internal/os/BinderInternal.java) * 在上面我們了解到 AndroidRuntime 會註冊所有的 JNI 方法,其中就包括 Binder JNI (`register_android_os_Binder`),現在我們來分析其中的 `int_register_android_os_BinderInternal` 方法 ```cpp= // android_util_Binder.cpp const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal"; static int int_register_android_os_BinderInternal(JNIEnv* env) { // 1. 獲取 BinderInternel 的類對象 jclass clazz = FindClassOrDie(env, kBinderInternalPathName); // 2. 將常用的類、方法、段 轉為全域 gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V"); gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V"); // 同上介紹,獲取與 Java 簽名對應的方法、類、段 jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray"); gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass); gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "<init>", "()V"); gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put", "(II)V"); BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback); // 3. 註冊 gBinderInternalMethods 陣列中的所有方法 return RegisterMethodsOrDie( env, kBinderInternalPathName, gBinderInternalMethods, NELEM(gBinderInternalMethods)); } ``` 其實這裡就跟 Binder 相同,所以這裡簡單介紹 1. 獲取 BinderInternel 的類對象 2. 透過 MakeGlobalxxx 方法,將 **全域參數** `gBinderInternalOffsets` 的 mClass、jmethodID、jfieldID 賦值 | JNI 全域儲存 | Java 對應 | | -------- | -------- | | mClass | BinderInternel 的 class 對象 | | mForceGc | BinderInternel#forceBinderGc 方法 | | mProxyLimitCallback | BinderInternel#binderProxyLimitCallbackFromNative 方法 | ```cpp= // android_util_Binder.cpp static struct binderinternal_offsets_t { // Class state. jclass mClass; jmethodID mForceGc; jmethodID mProxyLimitCallback; } gBinderInternalOffsets; ``` 3. 註冊 與 JNI 相對應的 Java 參數 ```cpp= // android_util_Binder.cpp static const JNINativeMethod gBinderInternalMethods[] = { /* name, signature, funcPtr */ { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool }, { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling }, { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads }, { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }, { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled }, { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts }, { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount }, { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} }; ``` ### JNI 註冊 - [BinderProxy 類](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/BinderProxy.java) * 在上面我們了解到 AndroidRuntime 會註冊所有的 JNI 方法,其中就包括 Binder JNI (`register_android_os_Binder`),現在我們來分析其中的 `int_register_android_os_BinderProxy` 方法 ```cpp= // android_util_Binder.cpp const char* const kBinderProxyPathName = "android/os/BinderProxy"; static int int_register_android_os_BinderProxy(JNIEnv* env) { ... 省略部份 // 1. 獲取 BinderProxy 的類對象 jclass clazz = FindClassOrDie(env, kBinderProxyPathName); // 2. 將常用的類、方法、段 轉為全域 gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance", "(JJ)Landroid/os/BinderProxy;"); gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V"); gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J"); ... 省略部份 // 3. 註冊 gBinderProxyMethods 陣列中的所有方法 return RegisterMethodsOrDie( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); } ``` 其實這裡就跟 Binder 相同,所以這裡簡單介紹 1. 獲取 BinderProxy 的類對象 2. 透過 MakeGlobalxxx 方法,將 **全域參數** `gBinderProxyOffsets` 的 mClass、jmethodID、jfieldID 賦值 | JNI 全域儲存 | Java 對應 | | -------- | -------- | | mClass | BinderProxy 的 class 對象 | | mGetInstance | BinderProxy#getInstance 靜態方法 | | mSendDeathNotice | BinderProxy#sendDeathNotice 方法 | | mNativeData | BinderProxy#mNativeData 成員 | ```cpp= // android_util_Binder.cpp static struct binderproxy_offsets_t { // Class state. jclass mClass; jmethodID mGetInstance; jmethodID mSendDeathNotice; // Object state. jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData. } gBinderProxyOffsets; ``` 3. 註冊 與 JNI 相對應的 Java 參數 ```cpp= // android_util_Binder.cpp static const JNINativeMethod gBinderProxyMethods[] = { /* name, signature, funcPtr */ {"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}, {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer}, {"getExtension", "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension}, }; ``` ## Java Service 註冊 ### Java [ServiceManager](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/ServiceManager.java) - [AMS](https://cs.android.com/android/platform/superproject/+/master:out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/xref26/srcjars.xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java) 註冊 * 與 Android Native 層 `ServiceManager.cpp` 相對,在 Java 層也有一個 `ServiceManager.java` 文件,而 Java Service 註冊就需要通過 ServiceManager.java 類 > Java 層服務最終會註冊進 `ServiceManager.cpp` * 這邊用 AMS 為例:AMS 透過 aidl 實現,它繼承 `Binder.java` 所以可以判斷 AMS (ActivityManagerService) 是一個 Java Service 類 > ![](https://i.imgur.com/Wu7aksv.png) 1. 我們知道系統服務都是由 [**SystemServer**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/java/com/android/server/SystemServer.java) 啟動,當然 AMS 也在其中 ```java= // SystemServer.java private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { ... 省略部份 ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); ... 省略部份 // @ 追蹤 setSystemProcess 方法 mActivityManagerService.setSystemProcess(); } ``` 2. 註冊系統服務是通過 [**AMS**](https://cs.android.com/android/platform/superproject/+/master:out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/xref26/srcjars.xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)#`setSystemProcess` 方法,該方法會註冊許多服務,但我們這裡關注 AMS 註冊 | AMS 中註冊的服務 | 服務名 | | -------- | - | | ACTIVITY_SERVICE| activity | | ProcessStats | procstats | | 記憶體訊息 | meminfo | | 繪圖訊息 | gfxinfo | | 資料庫訊息 | dbinfo | | 權限訊息 | permission | | 進程訊息 | processinfo | | 快取訊息 | cacheinfo | ```java= // Context.java public static final String ACTIVITY_SERVICE = "activity"; // ---------------------------------------------------------------- // ActivityManagerService.java public void setSystemProcess() { try { // @ 追蹤 addService 方法 ServiceManager.addService( Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); ... 省略部份註冊 } /* 省略 catch */ ... 省略部份 } ``` 3. [**ServiceManager**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/ServiceManager.java)#addService 呼叫靜態方法 `getIServiceManager` 來添加服務 :::info * ServiceManager#`getIServiceManager` 方法會建立一個代理物件,透過該代理物件來訪問 Native 層的 ServiceManager ::: ```java= // ServiceManager.java // 緩存快取 (一個進程只會有一個 ServiceManager 代理物件) private static IServiceManager sServiceManager; public static void addService(String name, // "activity" IBinder service, // AM boolean allowIsolated, int dumpPriority) { try { // @ 追蹤 getIServiceManager 方法 getIServiceManager().addService(name, service, allowIsolated, dumpPriority); } /* 省略 catch */ } private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // @ 分析 sServiceManager = ServiceManagerNative.asInterface ( Binder.allowBlocking( BinderInternal.getContextObject() ) ); return sServiceManager; } ``` :::success * BinderInternal#`getContextObject` 方法:請參考另外一篇 [**取得 IServiceManager - 創建 BpBinder 代理**](https://hackmd.io/_8ne10VrSK-mK6nlyxL5RQ?view#%E5%8F%96%E5%BE%97-IServiceManager---%E5%89%B5%E5%BB%BA-BpBinder-%E4%BB%A3%E7%90%86) ::: > ![](https://i.imgur.com/RcN72rH.png) ### Java Service 創建代理 - 訪問 SerivceManager :::info 這裡會創建一個 BinderProxy ::: * 到 ServiceManager#getIServiceManager 方法後需要分析以下函數 | 待分析函數 | 功能 | | - | - | | BinderInternal.`getContextObject()` | 創建 Native 層 **BpBinder**、取得 Java 層 **BinderProxy** | | ServiceManagerNative.`asInterface()` | 創建 Java 層 ServiceManagerProxy 對象 | | getIServiceManager().`addService()` | AIDL 透過 BpBinder 傳送資料給 Binder 驅動 | 1. [**BinderInternal**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/com/android/internal/os/BinderInternal.java).getContextObject():其實就是呼叫 ProcessState#getContextObject,最終返回一個 IBinder 對象,該對象就是 [**BpBinder**](https://cs.android.com/android/platform/superproject/+/master:prebuilts/vndk/v31/x86/include/frameworks/native/libs/binder/include/binder/BpBinder.h;l=40?q=BpBinder&ss=android%2Fplatform%2Fsuperproject) ```java= // BinderInternal.java public static final native IBinder getContextObject(); ``` 從上面我們可以知道,該 Native JNI 會在 [**android_util_Binder**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp) 中註冊,並有對應處理的 JNI 函數 | Java 方法 | JNI 函數 | | -------- | -------- | | getContextObject | android_os_BinderInternal_getContextObject | ```cpp= // android_util_Binder.cpp static const JNINativeMethod gBinderInternalMethods[] = { /* name, signature, funcPtr */ { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject }, ... 省略部份 } static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { // ProcessState 進程單例 // getContextObject 最終返回 BpBinder sp<IBinder> b = ProcessState::self()->getContextObject(NULL); // 由於 Java 層無法直接使用 BpBinder (BpBinder 是 Native 層) // 所以要透過 javaObjectForIBinder 函數轉換 // @ 分析 javaObjectForIBinder return javaObjectForIBinder(env, b); } ``` :::success * ProcessState#getContextObject 分析請參考 [**創建 BpBinder**](https://hackmd.io/_8ne10VrSK-mK6nlyxL5RQ?view#%E5%8F%96%E5%BE%97-IServiceManager---%E5%89%B5%E5%BB%BA-BpBinder),並且它的實踐對象是由 aidl 產生出的 [**BpServiceManager**](https://cs.android.com/android/platform/superproject/+/master:prebuilts/vndk/v32/x86/include/generated-headers/frameworks/native/libs/binder/libbinder/android_vendor.32_x86_shared/gen/aidl/android/os/BpServiceManager.h) ::: 從這裡可以看出 **Java Binder 需要使用到 Native 的 BpBinder**,但由於不能直接使用,所以透過 `javaObjectForIBinder` 函數來取得 [**BinderProxy**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/BinderProxy.java) > BinderProxy 屬於 Java 層 ```cpp= // android_util_Binder.cpp // val 傳入可能是為 BpBinder (代理)、JavaBBinder(本地) jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) { ... // 檢查是否是本地 (JavaBBinder) 物件 if (val->checkSubclass(&gBinderOffsets)) { jobject object = static_cast<JavaBBinder*>(val.get())->object(); ... // 返回本地物件 return object; } // 透過 new 關鍵自來創建 BinderProxyNativeData 結構 BinderProxyNativeData* nativeData = new BinderProxyNativeData(); nativeData->mOrgue = new DeathRecipientList; nativeData->mObject = val; // gBinderProxyOffsets.mClass 存有 Java 層的 BinderProxy jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, // 透過 BinderProxy#getInstsance 取得 BinderProxy 對象 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get()); if (env->ExceptionCheck()) { return NULL; } ... 省略部份 return object; } // ---------------------------------------------------------------------------- // BinderProxy.java // nativeData 存有 BinderProxyNativeData 地址 // iBinder 存有 BpBinder 地址 private static BinderProxy getInstance(long nativeData, long iBinder) { BinderProxy result; synchronized (sProxyMap) { try { result = sProxyMap.get(iBinder); if (result != null) { return result; } result = new BinderProxy(nativeData); } catch (Throwable e) { ... 省略 catch 處理 throw e; } NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData); // The registry now owns nativeData, even if registration threw an exception. sProxyMap.set(iBinder, result); } return result; } ``` :::info * Java 層 BinderProxy 的創建是用 IBinder 作為 Key,可見得 **一個服務只會創建一個代理對象** * Java 層的 BinderProxy 可能會多個對一個 Native 層的 BpBinder ::: > ![](https://i.imgur.com/rOXE4UO.png) 2. [**ServiceManagerNative**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/ServiceManagerNative.java)#asInterface 方法:**創建 ServiceManagerProxy 對象**,從這裡可以看出 Proxy 對象被一層層包裝 (如下圖) > ![](https://i.imgur.com/DqA2b9c.png) ```java= // ServiceManagerNative.java // 傳入的 obj 為 BinderProxy public static IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } // ServiceManager is never local return new ServiceManagerProxy(obj); } class ServiceManagerProxy implements IServiceManager { // mRemote 就是 BinderProxy private IBinder mRemote; private IServiceManager mServiceManager; // 傳入 BinderProxy public ServiceManagerProxy(IBinder remote) { mRemote = remote; mServiceManager = IServiceManager.Stub.asInterface(remote); } ... 省略部份方法 } ``` :::info * [**IServiceManager**](https://cs.android.com/android/platform/superproject/+/master:out/soong/.intermediates/frameworks/base/framework-minus-apex-intdefs/android_common/xref33/srcjars.xref/android/os/IServiceManager.java;l=13;drc=6c337f5f25cd58b3c45606f9d875b75e37cadbee;bpv=1;bpt=1) 是由 aidl 產生,所以這邊我們省略 `IServiceManager.Stub.asInterface` 方法,先知道它會返回與 Binder 通訊的代理類 ::: > ![](https://i.imgur.com/tINs1Zm.png) 所以以上程式可以簡化為如下 ```java= // 偽程式 private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // @ 簡化 sServiceManager = new ServiceManagerProxy(new BinderProxy()); return sServiceManager; } ``` 3. **getIServiceManager().addService 方法**:從上面我們可以知道 `getIServiceManager` 返回的是 `ServiceManagerProxy`,所以這邊查看 [**ServiceManagerProxy**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/ServiceManagerNative.java;l=50;drc=1b1e0e28fff9b2add0176e5595dfb3497769204f;bpv=1;bpt=1)#addService 方法 :::danger * 這裡有個重點:Proxy 會把對象 (AMS)透過 Parcel#**writeStrongBinder** 寫入到 Parcel 包裹中 Parcel#writeStrongBinder 方法之後會在分析 ::: ```java= // ServiceManagerNative.java class ServiceManagerProxy implements IServiceManager { // mRemote 就是 BinderProxy private IBinder mRemote; // mServiceManager 由 aidl 產生 private IServiceManager mServiceManager; // 目前傳入的 service 是 AMS public void addService(String name, // "activity" IBinder service, // AMS boolean allowIsolated, int dumpPriority) throws RemoteException { mServiceManager.addService(name, service, allowIsolated, dumpPriority); } ... 省略部份方法 } // --------------------------------------------------------------- // IServiceManager.java (aidl 產生) private static class Proxy implements android.os.IServiceManager { // 該 remote 就是 BinderProxy 對象 private android.os.IBinder mRemote; @Override public void addService(java.lang.String name, android.os.IBinder service, boolean allowIsolated, int dumpPriority) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeString(name); // 目前傳入的 service 是 AMS 對象 _data.writeStrongBinder(service); _data.writeBoolean(allowIsolated); _data.writeInt(dumpPriority); // 呼叫 BinderProxy#transact 方法 // @ 追蹤 transact boolean _status = mRemote.transact(Stub.TRANSACTION_addService, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } ``` > ![](https://i.imgur.com/ZsSNPxw.png) 呼叫 [**BinderProxy**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/BinderProxy.java)#`transact` 方法(java 層),該方法會呼叫到 JNI 的 `android_os_BinderProxy_transact` 方法 ```java= // BinderProxy.java public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { try { // @ 追蹤 transactNative 方法 final boolean result = transactNative(code, data, reply, flags); ... 省略部份 return result; } /* 省略 finally */ } // @ 追蹤 transactNative public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException; ``` | Java 方法 | JNI 對應函數 | | -------- | -------- | | transactNative | android_os_BinderProxy_transact | :::success * 在這裡會使用 mObject 來取得 BpBinder 對象(**在 BinderInternal#getContextObject 就會創建 BpBinder 並儲存在 BinderProxy#mObject**) ```java= // BinderProxy.java // nativeData 存有 BinderProxyNativeData 地址 // iBinder 存有 BpBinder 地址 private static BinderProxy getInstance(long nativeData, long iBinder) { BinderProxy result; synchronized (sProxyMap) { try { result = sProxyMap.get(iBinder); if (result != null) { return result; } result = new BinderProxy(nativeData); } catch (Throwable e) { ... 省略 catch 處理 throw e; } NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData); // The registry now owns nativeData, even if registration threw an exception. sProxyMap.set(iBinder, result); } return result; } ``` ::: * 最終 JNI 層會呼叫 BpBinder#transact 來傳送資料到 ServiceManager ```cpp= // android_util_Binder.cpp struct BinderProxyNativeData { // The native IBinder proxied by this BinderProxy. sp<IBinder> mObject; ... }; static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException { ... 省略檢查 // 將 Java Parcel 轉換成 Native Parcel Parcel* data = parcelForJavaObject(env, dataObj); if (data == NULL) { return JNI_FALSE; } Parcel* reply = parcelForJavaObject(env, replyObj); if (reply == NULL && replyObj != NULL) { return JNI_FALSE; } // mObject 就是 BpBinder IBinder* target = getBPNativeData(env, obj)->mObject.get(); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } ... 省略部份 // 呼叫到 BpBinder#transact 函數 status_t err = target->transact(code, *data, reply, flags); ... 省略部份 return JNI_FALSE; } ``` > ![](https://i.imgur.com/3hUJn6S.png) ### Java Service 啟動過程 :::success Java Service 啟動過程 也就是 Service 創建 [JavaBinderHolder](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp) 時機 ::: * AIDL 創建的文件中 Sub 類,它繼承於 [**Binder.java**](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Binder.java) 分析 **++Binder 建構函數++**:Binder 在建構函數中呼叫 getNativeBBinderHolder 函數,它會創建 JavaBBinderHolder 對象 ```java= // /android/os/Binder.java private final long mObject; public Binder(@Nullable String descriptor) { // 呼叫Native 函數 (儲存 JavaBBinderHolder 對象的 ptr) mObject = getNativeBBinderHolder(); ... mDescriptor = descriptor; } private static native long getNativeBBinderHolder(); ``` * 透過 Binder#getNativeBBinderHolder 方法:把 **在 Native 創建的 JavaBBinderHolder 對象指針存到 Java 端 Binder#mObject**(之後會使用到) | Java 方法 | JNI 對應函數 | | -------- | -------- | | getNativeBBinderHolder | android_os_Binder_getNativeBBinderHolder | ```cpp= // /core/jni/android_util_Binder.cpp static const JNINativeMethod gBinderMethods[] = { ... { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder }, } static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz) { // 創建 JavaBBinderHolder JavaBBinderHolder* jbh = new JavaBBinderHolder(); return (jlong) jbh; } ``` :::info 透過將 JavaBBinderHolder 地址返回給 Java 層,Java 層就可以透過 `mObject` 成員來取得 JavaBBinderHolder > 也就是將 JavaBBinderHolder 地址存在 JavaBinder 中 ::: * 來看 [**JavaBBinderHolder**](https://cs.android.com/android/platform/superproject/+/android-10.0.0_r2:frameworks/base/core/jni/android_util_Binder.cpp) 成員,就可以知道它的工作是負責銜接 Native BBinder & Java Service ```cpp= // android_util_Binder.cpp class JavaBBinderHolder { public: JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object) : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)) { ... } private: wp<JavaBBinder> mBinder; // 指向 Native BBinder jobject const mObject; // 指向 Java Service 地址 } ``` ### Java Service 透過代理物件 - addService :::info [**JavaBBinder**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp) 寫入 Service ::: 目前是透過 BinderProxy 來訪問 ServiceManager,並把 AMS 服務存入 ServiceManager ```cpp= // IServiceManager.java (aidl 產生) private static class Proxy implements android.os.IServiceManager { // 該 remote 就是 BinderProxy 對象 private android.os.IBinder mRemote; @Override public void addService(java.lang.String name, android.os.IBinder service, boolean allowIsolated, int dumpPriority) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { ... // 服務名稱 _data.writeString(name); // 目前傳入的 service 是 AMS 對象 // @ 分析 writeStrongBinder 方法 _data.writeStrongBinder(service); ... // 呼叫 BinderProxy#transact 方法 boolean _status = mRemote.transact( Stub.TRANSACTION_addService, _data, _reply, 0); ... } /* 省略 finally */ } } ``` :::success 以指針的方式寫入,Native & Kernel 才能調用 ::: * 我們從上面 Proxy#addService 方法,使用 [**Parcel**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Parcel.java) 打包要傳送的數據開始,並且這裡我們 **主要關注 Parcel#`writeStrongBinder` 方法** ```java= // Parcel.java public final void writeStrongBinder(IBinder val) { // @ 查看 nativeWriteStrongBinder nativeWriteStrongBinder(mNativePtr, val); } // @ JNI 方法 private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); ``` | Java 方法 | JNI 對應函數 | | -------- | -------- | | nativeWriteStrongBinder | android_os_Parcel_writeStrongBinder | nativeWriteStrongBinder 實做 JNI 方法在 [**android_os_Parcel**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_os_Parcel.cpp) ```java= // android_os_Parcel.cpp 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) { // 1. 追蹤 @ ibinderForJavaObject 函數 // 2. 之後追蹤 @ writeStrongBinder 函數 const status_t err = parcel->writeStrongBinder( ibinderForJavaObject(env, object) ); if (err != NO_ERROR) { signalExceptionForError(env, clazz, err); } } } // obj // 可能是代理物件 // 也可能是本 Service 物件 sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; // 取得 Java 層 Binder 實例 (當前狀況 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { // 獲取 JavaBBinderHolder 對象 (創建 JavaBBinderHolder 時機上面有說明) JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject); // 取得 JavaBBinder // 查看 @ get 函數 return jbh->get(env, obj); } // 取得 Java 層 BinderProxy 實例 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return getBPNativeData(env, obj)->mObject; } return NULL; } ``` * 查看 JavaBinderHolder#get 方法取得 JavaBBinder 對象 ```cpp= // android_util_Binder.cpp class JavaBBinderHolder { public: sp<JavaBBinder> get(JNIEnv* env, jobject obj) { AutoMutex _l(mLock); // 升級弱指針到強指針 sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { // 創建一個 JavaBBinder 對象 (AMS 服務) b = new JavaBBinder(env, obj); ... if (mExtension != nullptr) { b.get()->setExtension(mExtension); } mBinder = b; } return b; } private: Mutex mLock; wp<JavaBBinder> mBinder; ... sp<IBinder> mExtension; } ``` > ![](https://i.imgur.com/g4DgTTD.png) :::info 從這邊可以看出,在準備傳出資料時,才會將 JavaBBinder & JavaBBinderHolder 兩者進行連接 ::: * 到這裡我們可以產生一個偽代碼,也就是 `writeStrongBinder` 其實寫入的是一個包裝對象,真正的內容在包裝內 ```cpp= // 偽代碼 parcel.writeStrongBinder(new JavaBBinder(env, IBinder)); // 這個 IBinder 就是 AMS ``` > ![](https://i.imgur.com/wVhyfrt.png) ### [Parcel](https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/binder/Parcel.cpp) - 打包 Service 資料 * 上面有分析過 `ibinderForJavaObject` 功能是在獲取 JavaBBinder 對象,現在分析 [**Parcel**](https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/binder/Parcel.cpp)#**writeStrongBinder** 函數 ```java= // android_os_Parcel.cpp 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) { // @ 追蹤 writeStrongBinder 函數 const status_t err = parcel->writeStrongBinder( ibinderForJavaObject(env, object) // JavaBBinder ); ... } } ``` * [**Parcel**](https://cs.android.com/android/platform/superproject/+/master:frameworks/native/libs/binder/Parcel.cpp)#**writeStrongBinder** 函數,把 JavaBBinder (AMS 的 IBinder) 寫入 `flat_binder_object` 結構 > ![](https://i.imgur.com/SO4YrRO.png) ```cpp= // Parcel.cpp status_t Parcel::writeStrongBinder(const sp<IBinder>& val) { // @ 追蹤 flattenBinder return flattenBinder(val); } // 目前 binder 是 JavaBBinder (AMS Service) status_t Parcel::flattenBinder(const sp<IBinder>& binder) { BBinder* local = nullptr; // 目前寫入的對象是 AMS(Service),local 是 null if (binder) local = binder->localBinder(); ... 省略部份 flat_binder_object obj; ... 省略部份 if (binder != nullptr) { if (!local) { // 非本地 Service BpBinder *proxy = binder->remoteBinder(); ... 省略部份 const int32_t handle = proxy ? proxy->getPrivateAccessor().binderHandle() : 0; obj.hdr.type = BINDER_TYPE_HANDLE; obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ obj.flags = 0; obj.handle = handle; obj.cookie = 0; } else { // 本地 Service ( 當前狀況 int policy = local->getMinSchedulerPolicy(); int priority = local->getMinSchedulerPriority(); ... 省略部份 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS; ... 省略部份 obj.hdr.type = BINDER_TYPE_BINDER; obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); obj.cookie = reinterpret_cast<uintptr_t>(local); } } else { .. } obj.flags |= schedBits; status_t status = writeObject(obj, false); if (status != OK) return status; return finishFlattenBinder(binder); } status_t Parcel::finishFlattenBinder(const sp<IBinder>& binder) { ... 省略部份 return writeInt32(rep); // 寫入資料 } ``` ### Java 註冊服務 - 結論 * Java 層服務是透過 JavaBBinder 註冊到 ServiceManager 中,所以 Client 在訪問 Service 時,其實就是在訪問 Service 的 JavaBBinder > ![](https://i.imgur.com/rzLPOgb.png) ## Java Client 訪問 Service ### Java Client 取得代理 * 以下是 ActivityManager 透過取得代理來跟 AMS 通訊的方式並分析兩個方法:^1.^ ServiceManager#`getService`、^2.^ IActivityManager.Stub#`asInterface` ```java= private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { // 取得 Java 訪問 AMS 的代理物件 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); // 透過 `asInterface` 方法,將 Java 代理物件再次包裝 final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } }; ``` 1. [**ServiceManager**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/ServiceManager.java)#`getService`:最終可以取得目標 Java Service (AMS) 的 Java 代理物件服務代理物件 > ![](https://i.imgur.com/4391Ppf.png) ```java= // ServiceManager.java // 快取 private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>(); public static IBinder getService(String name) { try { // 取得 Java 服務代理物件 IBinder service = sCache.get(name); if (service != null) { return service; } else { return Binder.allowBlocking( // @ 查看 rawGetService 方法 rawGetService(name) ); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } private static IBinder rawGetService(String name) throws RemoteException { final long start = sStatLogger.getTime(); // 透過 getIServiceManager 取得訪問 ServiceManager 的代理物件 // 訪問 ServiceManager#getService 方法 final IBinder binder = getIServiceManager().getService(name); ... 省略部分 return binder; } ``` 2. [**IActivityManager**](https://cs.android.com/android/platform/superproject/+/master:out/soong/.intermediates/frameworks/base/framework-minus-apex/android_common/xref35/srcjars.xref/android/app/IActivityManager.java).Stub#`asInterface`:將 Java 層的 BinderProxy 再次包裝,包裝成專屬 `IActivityManager` 的代理類 ```java= // IActivityManager.java public static android.app.IActivityManager asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof android.app.IActivityManager))) { return ((android.app.IActivityManager)iin); } return new android.app.IActivityManager.Stub.Proxy(obj); } ``` > ![](https://i.imgur.com/grEkGWR.png) ### Java Service - 分析 [JavaBBinder](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/jni/android_util_Binder.cpp) 功能 :::success Client 訪問 Java Service 時,BinderDriver 會將資料傳給 ^1.^ 對應的 BpBinder,再傳給 ^2.^ JavaBBinder,最後傳到 ^3.^ Java Service ::: * 我們知道 Native Service 服務都需要繼承於 Native BBinder,在 Java 層使用的 JavaBBinder 也繼承於 BBinder,也就是 **透過 JavaBBinder 將 Java Service 轉為 Native BBinder** ```cpp= // android_util_Binder.cpp class JavaBBinder : public BBinder { public: 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); } ... } ``` * 當 Binder 驅動收到用戶請求後就會觸發 Server 端 BBinder 的 `onTransact` 函數,而該函數在 Java 層 Service 就是由 JavaBBinder 實做 :::info Binder 驅動如何 [**BBinder 觸發 onTransact**](https://hackmd.io/7HfNn3P4QP29cZbl5N79oA?view#ServiceManager-%E7%B9%BC%E6%89%BF-BBinder---onTransact-%E8%99%95%E7%90%86%E5%91%BD%E4%BB%A4),請參考另一篇文章 ::: ```cpp= // android_util_Binder.cpp class JavaBBinder : public BBinder { public: ... protected: status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override { JNIEnv* env = javavm_to_jnienv(mVM); ...log 訊息 IPCThreadState* thread_state = IPCThreadState::self(); const int32_t strict_policy_before = thread_state->getStrictModePolicy(); // 呼叫 Java 層 Binder#execTransact 方法 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags); ... 省略部份 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; } } ``` Native 層 **JavaBBinder#onTransact 會呼叫 ++Java 層 [Binder](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/Binder.java)#execTransact 方法++**,最終會呼叫到 onTransact 方法 ```java= // Binder.java private boolean execTransact(int code, long dataObj, long replyObj, int flags) { // 此時,包裹請求標頭還沒有被解析,所以我們不知道調用者設置了什麼 // // 使用調用者的 Uid 作為預設值 final int callingUid = Binder.getCallingUid(); final long origWorkSource = ThreadLocalWorkSource.setUid(callingUid); try { // @ execTransactInternal return execTransactInternal(code, dataObj, replyObj, flags, callingUid); } finally { ThreadLocalWorkSource.restore(origWorkSource); } } private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags, int callingUid) { ... Parcel data = Parcel.obtain(dataObj); Parcel reply = Parcel.obtain(replyObj); boolean res; ... try { ... 省略部份 if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0) { ... } else { // @ onTransact res = onTransact(code, data, reply, flags); } } catch (RemoteException|RuntimeException e) { ... if ((flags & FLAG_ONEWAY) != 0) { ... log 訊息 } else { // Clear the parcel before writing the exception. reply.setDataSize(0); reply.setDataPosition(0); reply.writeException(e); } res = true; } finally { ... reply.recycle(); data.recycle(); } return res; } ``` 像當前狀況 [**ActivityManagerService**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java;l=441?q=ActivityManagerService&ss=android%2Fplatform%2Fsuperproject)、IActivityManager.Stub(aidl 產生) 會 override Binder#onTransact 方法,處理相對應的方法 ```java= @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { ...處理相對應的 code } ``` ## Appendix & FAQ :::info ::: ###### tags: `Binder`