---
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 端 |
> 
## 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;
}
```
> 
### 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 類
> 
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)
:::
> 
### 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
:::
> 
2. [**ServiceManagerNative**](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/ServiceManagerNative.java)#asInterface 方法:**創建 ServiceManagerProxy 對象**,從這裡可以看出 Proxy 對象被一層層包裝 (如下圖)
> 
```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 通訊的代理類
:::
> 
所以以上程式可以簡化為如下
```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();
}
}
}
```
> 
呼叫 [**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;
}
```
> 
### 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;
}
```
> 
:::info
從這邊可以看出,在準備傳出資料時,才會將 JavaBBinder & JavaBBinderHolder 兩者進行連接
:::
* 到這裡我們可以產生一個偽代碼,也就是 `writeStrongBinder` 其實寫入的是一個包裝對象,真正的內容在包裝內
```cpp=
// 偽代碼
parcel.writeStrongBinder(new JavaBBinder(env, IBinder)); // 這個 IBinder 就是 AMS
```
> 
### [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` 結構
> 
```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
> 
## 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 代理物件服務代理物件
> 
```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);
}
```
> 
### 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`