当你的 App 调用
registerContentObserver()注册一个观察者时,你的ContentObserver明明是 App 进程里的一个 Java 对象,system_server 是怎么把它"持有"在自己进程里的?数据变化时,system_server 又是怎么跨进程"调用"到你这个对象的?
先搞懂几个问题
JavaBBinder:Java Binder 的 Native 层的对象
问题:Transport 已经继承了 android.os.Binder(Java 层),为什么还需要在 Native 层再创建一个 JavaBBinder?
答案是它承担了两个无法绕开的核心职责:
-
作为 Java Binder 的 Native 实体包装 。
JavaBBinder继承自BBinder,使 JavaBinder能接入 Native Binder 框架。flat_binder_object中的binder是JavaBBinder的weakRefs指针,cookie是JavaBBinder*;Binder 驱动把两者当作发送进程用户空间的 opaque 标识值,用它们查找或创建binder_node,而不是解引用并理解 JavaBBinder 对象。 -
桥接 Native 回调到 Java 。
JavaBBinder通过NewGlobalRef持有 Java 对象,当驱动把跨进程调用投递回来时,JavaBBinder::onTransact()通过 JNI 的CallBooleanMethod回调 Java 层的Binder.execTransact(),从而进入 Java 业务代码
asInterface:本地还是远程
AIDL 生成的 Stub.asInterface() 是所有 Binder 接口的统一入口,它的判断逻辑:
Java
public static IContentObserver asInterface(IBinder obj) {
if (obj == null) return null;
IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (iin != null) return (IContentObserver) iin; // 同进程:直接返回本地 Stub
return new IContentObserver.Stub.Proxy(obj); // 跨进程:返回代理
}
关键在于 queryLocalInterface() 的两个实现:
-
Binder.queryLocalInterface():如果 descriptor 匹配,返回mOwner(本地 Stub 自己); -
BinderProxy.queryLocalInterface():永远返回 null------因为它本身就是远程代理,不是本地实体。
所以在 system_server 里拿到 BinderProxy 后调 asInterface,必然走 new Proxy(obj) 分支;构造函数再执行 mRemote = obj,后续所有方法调用都经 BinderProxy.transact() 发起跨进程请求。
案例背景:一次注册,三段旅程
先看应用层的用法,就一行代码:
java
// App 进程:注册一个内容观察者
Uri uri = Settings.Global.getUriFor("airplane_mode_on");
getContentResolver().registerContentObserver(uri, false, mObserver);
这一行代码背后,mObserver 要完成一次"跨进程变身":
-
第一幕(App 进程) :
ContentObserver内部的Transport(继承IContentObserver.Stub,也就是继承Binder)作为特殊 Binder 对象被扁平化进 Parcel------Java 对象经过 JNI 层层转换,最终形成一个flat_binder_object{type=BINDER_TYPE_BINDER}写进数据缓冲区; -
第二幕(内核) :Binder 驱动发现这个
BINDER_TYPE_BINDER,调用binder_translate_binder()把它改写成BINDER_TYPE_HANDLE,并在两个进程里分别登记实体和引用; -
第三幕(system_server) :ContentService 的 Binder 线程收到事务,读参数时把 handle 还原成
BinderProxy(Java 代理对象)
完整链路一图总结
Markdown
App 进程 Kernel system_server 进程
① new ContentObserver(handler)
② getContentObserver()
→ new Transport(this)
Transport = Binder 实体
地址: 0xAAAA
③ Stub$Proxy.registerContentObserver()
→ writeStrongInterface(observer)
→ flattenBinder:
flat_binder_object{
type=BINDER_TYPE_BINDER,
binder=0xAAAA,
cookie=0xBBBB
}
④ mRemote.transact(BC_TRANSACTION) ──→ ⑤ binder_transaction()
④ ioctl 目标查找:
handle → ref → target_node(ContentService)
target_proc = system_server
⑥ 遍历 flat_binder_object:
case BINDER_TYPE_BINDER
→ binder_translate_binder()
⑦ 在 App 进程创建/查找 binder_node:
binder_get_node(0xAAAA)
→ node (Transport 的 node)
⑧ 在 system_server 进程创建/查找 binder_ref:
binder_inc_ref_for_node(system_server, node)
→ ref, handle=42
⑨ 修改 flat_binder_object:
BINDER_TYPE_BINDER → BINDER_TYPE_HANDLE
fp->handle = 42
⑩ 拷贝到 system_server mmap 映射区
⑪ binder_proc_transaction() → 唤醒 ──→ ⑫ BR_TRANSACTION
IPCThreadState::executeCommand()
buffer 指向 mmap 映射区
(含 flat_binder_object{HANDLE, handle=42})
⑬ JavaBBinder::onTransact
→ Binder.execTransact
→ Stub.onTransact
case registerContentObserver
⑭ data.readStrongBinder()
→ unflattenBinder()
读出 flat_binder_object{HANDLE, handle=42}
→ getStrongProxyForHandle(42)
→ BpBinder(42) [第3层去重]
⑮ javaObjectForIBinder(BpBinder(42))
→ BinderProxy.getInstance(nativeData, 0x7F00)
→ sProxyMap.get(0x7F00) [第4层去重]
→ 未命中: new BinderProxy
→ sProxyMap.set(0x7F00, WeakRef)
★★★ ProxyMap +1 ★★★
⑯ asInterface(BinderProxy)
→ Stub.Proxy(BinderProxy)
⑰ ContentService.registerContentObserver()
→ mRootNode.addObserverLocked(observer)
→ mObservers.add(new ObserverEntry(observer))
→ ObserverEntry.observer = Stub.Proxy(BinderProxy)
★★★ 强引用持有 ★★★
⑱ linkToDeath(observer)
→ 注册死亡监听
⑲ BR_REPLY ←────────────────────────── reply.writeNoException()
④ waitForResponse 收到 reply ←────────── ⑳ transact 返回
⑤ 注册完成
App 创建 Transport(Binder 实体)
Java
// frameworks/base/core/java/android/content/ContentResolver.java:2727
public final void registerContentObserver(Uri uri, boolean notifyForDescendants,
ContentObserver observer, @CanBeALL @CanBeCURRENT @UserIdInt int userHandle) {
try {
// 【注释 1】observer.getContentObserver() 获取 Transport(IContentObserver.Stub),
// IContentObserver 作为 Binder 对象跨进程传递
getContentService().registerContentObserver(uri, notifyForDescendants,
observer.getContentObserver(), userHandle, mTargetSdkVersion);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
// Transport 是 ContentObserver 的私有内部类,它是真正的 Binder 实体
// frameworks/base/core/java/android/database/ContentObserver.java:86
public IContentObserver getContentObserver() {
synchronized (mLock) {
// 【注释 1】懒初始化:首次调用创建 Transport(IContentObserver.Stub),
// Transport 构造时触发 Java 构造函数链:
// Transport.<init>() -> 隐式 super() -> IContentObserver.Stub.<init>()
// -> 隐式 super() -> Binder.<init>() -> getNativeBBinderHolder()
// 后续复用同一实例
if (mTransport == null) {
mTransport = new Transport(this);
}
return mTransport;
}
}
Java
// frameworks/base/core/java/android/os/Binder.java:732
public Binder(@Nullable String descriptor) {
// 【注释 2】调用 JNI 创建 JavaBBinderHolder(注意:不是 JavaBBinder),
// JavaBBinderHolder 内部 mBinder 是 wp<JavaBBinder> 弱引用,初始为 null,
// JavaBBinder 将在第一次 ibinderForJavaObject() 调用时延迟创建
mObject = getNativeBBinderHolder();
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
// ... 泄漏检测省略 ...
mDescriptor = descriptor;
}
cpp
// frameworks/base/core/jni/android_util_Binder.cpp:1230
static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
{
// 【注释 1】仅创建 JavaBBinderHolder,不创建 JavaBBinder
// JavaBBinderHolder 内部 mBinder (wp<JavaBBinder>) 初始为 null
// JavaBBinder 将在第一次 jbh->get() 调用时延迟创建
JavaBBinderHolder* jbh = new JavaBBinderHolder();
return (jlong) jbh;
}
扁平化:writeStrongBinder 的 JNI 之旅。getContentService() 返回的是 AIDL 生成的 Proxy,调用 registerContentObserver。
java
// out/soong/.../gen/aidl/java/IContentService.java:1032-1050
@Override public void registerContentObserver(Uri uri, boolean notifyForDescendants,
IContentObserver observer, int userHandle, int targetSdkVersion)
throws RemoteException {
Parcel _data = Parcel.obtain(asBinder());
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeTypedObject(uri, 0);
_data.writeBoolean(notifyForDescendants);
// observer.asBinder() 返回 Transport 自身,随后进入 writeStrongBinder 的 JNI 扁平化路径。
_data.writeStrongInterface(observer);
_data.writeInt(userHandle);
_data.writeInt(targetSdkVersion);
// mRemote 是 ContentService 的 BinderProxy:注册请求方向为 App → system_server。
// 它不会在此调用 App 的 Transport.onChangeEtc。
boolean _status = mRemote.transact(
Stub.TRANSACTION_registerContentObserver, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
注意:
Transport.onChangeEtc()属于后续的反向通知 链路。system_server 从mRootNode.mObservers取出IContentObserver.Stub.Proxy后,调用其mRemote.transact(TRANSACTION_onChangeEtc, ..., FLAG_ONEWAY),再经 Binder 驱动回到 App 的 Transport;它不属于本次注册请求的正向调用。
Plain
// frameworks/base/core/java/android/os/Parcel.java:1366
public final void writeStrongBinder(IBinder val) {
// 【注释 1】nativePtr 是 Native Parcel 指针,val 是 Java Binder 对象(Transport)
// 调用 JNI nativeWriteStrongBinder
nativeWriteStrongBinder(mNativePtr, val);
}
JNI 桥接函数里,最关键的一步是 ibinderForJavaObject()------把 Java 对象换成 Native 对象
cpp
// frameworks/base/core/jni/android_os_Parcel.cpp:340
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz,
jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// 【注释 1】ibinderForJavaObject 将 Java Transport 转为 Native sp<IBinder>(JavaBBinder)
// 然后 parcel->writeStrongBinder 调用 flattenBinder 进行 Binder 对象扁平化
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
这里有两个分支:本地 Binder(Binder 子类)走 Holder 延迟创建;远程代理(BinderProxy 子类)直接返回已存在的 BpBinder
C++
// frameworks/base/core/jni/android_util_Binder.cpp:985
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
// 【注释 1】如果是 Binder 子类(本地服务端):
// Transport 继承 IContentObserver.Stub 继承 Binder,走这个分支
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
// 从 Java Binder 对象的 mObject 字段取出 JavaBBinderHolder 指针
// mObject 是在 Binder.<init>() 时通过 getNativeBBinderHolder() JNI 创建的
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
if (jbh == nullptr) {
ALOGE("JavaBBinderHolder null on binder");
return nullptr;
}
// 【注释 2】调用 jbh->get() 获取 JavaBBinder
// 首次调用时会延迟创建 JavaBBinder(见下一方法)
return jbh->get(env, obj);
}
// 【注释 3】如果是 BinderProxy 子类(远程代理):
// 直接返回 Native 层已有的 BpBinder(system_server 侧反序列化走这个分支)
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return getBPNativeData(env, obj)->mObject;
}
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
最后一步,Native 的 Parcel::writeStrongBinder 桥接到 flattenBinder
Plain
// frameworks/native/libs/binder/Parcel.cpp:1523
status_t Parcel::writeStrongBinder(const sp<IBinder>& val) {
return flattenBinder(val);
}
Plain
// frameworks/native/libs/binder/Parcel.cpp:253
status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
BBinder* local = nullptr;
if (binder) local = binder->localBinder();
if (local) local->setParceled();
// ... RPC 分支省略 ...
#ifdef BINDER_WITH_KERNEL_IPC
flat_binder_object obj;
// ... 调度策略 flags 省略 ...
if (binder != nullptr) {
if (!local) {
// 【注释】远程 Binder(BpBinder):写入 BINDER_TYPE_HANDLE
BpBinder *proxy = binder->remoteBinder();
const int32_t handle = proxy ? proxy->getPrivateAccessor().binderHandle() : 0;
obj.hdr.type = BINDER_TYPE_HANDLE;
obj.binder = 0;
obj.flags = 0;
obj.handle = handle;
obj.cookie = 0;
} else {
// 【注释】本地 Binder(JavaBBinder):写入 BINDER_TYPE_BINDER
// 这是本场景路径(App 进程发送 Transport)
obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
// ... 其他 flags 省略 ...
// 【关键】标记为本地 Binder,供 Binder 驱动识别和转换
obj.hdr.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); // 内核标识
obj.cookie = reinterpret_cast<uintptr_t>(local); // JavaBBinder 指针
}
} else {
obj.hdr.type = BINDER_TYPE_BINDER;
obj.flags = 0;
obj.binder = 0;
obj.cookie = 0;
}
// 【注释 4】将 flat_binder_object 写入 Parcel 数据缓冲区
status_t status = writeObject(obj, false);
if (status != OK) return status;
return finishFlattenBinder(binder);
#endif
}
至此,Parcel 里躺着一个 flat_binder_object{type=BINDER_TYPE_BINDER}。这个 Parcel 被 mRemote.transact() 送进内核
mRemote.transact 到 BC_TRANSACTION 的完整链路
Plain
Proxy.writeStrongInterface(observer) 之后会执行同步调用:
mRemote.transact(TRANSACTION_registerContentObserver, _data, _reply, 0);
mRemote.transact() [Java BinderProxy]
→ BinderProxy.transact() BinderProxy.java:534
→ transactNative() → JNI BinderProxy.java:622
→ android_os_BinderProxy_transact() android_util_Binder.cpp:1512
→ 取 BpBinder:getBPNativeData->mObject
→ BpBinder::transact() BpBinder.cpp:366
→ IPCThreadState::transact(handle,...) IPCThreadState.cpp:868
→ writeTransactionData(BC_TRANSACTION) IPCThreadState.cpp:1298
→ 组装 binder_transaction_data 写入 mOut ← BC_TRANSACTION 入缓冲
→ waitForResponse()
→ talkWithDriver() IPCThreadState.cpp:1179
→ ioctl(BINDER_WRITE_READ) [mOut 作 write_buffer]
→ binder_ioctl_write_read binder.c:5712
→ binder_thread_write binder.c:4355
→ case BC_TRANSACTION: copy_from_user (binder.c:4568)
→ binder_transaction() binder.c:3254 ← 进入第二幕
IPCThreadState::transact():组装准备
C++
// frameworks/native/libs/binder/IPCThreadState.cpp:868
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
LOG_ALWAYS_FATAL_IF(data.isForRpc(),
"Parcel constructed for RPC, but being used with binder.");
status_t err;
// 【注释 1】给事务打上"接受 FD"标记
flags |= TF_ACCEPT_FDS;
// ...
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
// 【注释 2】关键一步:以 BC_TRANSACTION 为命令码,把 handle/code/Parcel 数据 写入 mOut 缓冲区
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
// 【注释 3】同步事务(注册/查询类):阻塞等待回复
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
// ...
} else {
// 【注释 4】oneway 事务(回调通知类 onChangeEtc):不等待回复
err = waitForResponse(nullptr, nullptr);
}
return err;
}
// frameworks/native/libs/binder/IPCThreadState.cpp:1074-1080
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult) {
uint32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break; // ← 桥接 6b → 桥接 7
// ... 处理 kernel 返回的 BR_* 命令 ...
cmd = (uint32_t)mIn.readInt32();
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
break; // 继续等
case BR_REPLY: // (实际是 default 分支处理)
// 读取 reply 数据
goto finish;
// ...
}
}
}
用一张图总结内核里的登记动作
Plain
App 进程 Binder 驱动(内核) system_server
┌────────────────┐ ┌──────────────────────────┐ ┌────────────────┐
│ JavaBBinder │◄─cookie──│ binder_node │ │ binder_ref │
│ (BBinder 实体) │ │ .ptr = weakrefs 指针 │◄───────│ .desc = 42 │
│ │ │ .cookie = JavaBBinder* │ 引用 │ .node = node │
└────────────────┘ └──────────────────────────┘ └────────────────┘
三件事:
-
App 进程侧:
binder_node登记实体(cookie保存 JavaBBinder 指针------回调的钥匙); -
system_server 侧:
binder_ref登记引用,分配句柄(比如 42); -
数据本身:
flat_binder_object被就地改写成句柄形态
system_server 创建 BinderProxy(代理)
Plain
system_server 的 Binder 线程会阻塞在 binder_thread_read() 里等待工作。事务到达后,驱动唤醒它,它把事务打包成 BR_TRANSACTION 写回用户空间
// kernel: drivers/android/binder.c:4969
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
{
// ...
// 【注释 1】阻塞等待:线程在此睡眠
// 当 App 进程发起 BC_TRANSACTION,binder_transaction() 将事务放入
// system_server 的 todo 队列并唤醒本线程
ret = binder_wait_for_work(thread, wait_for_proc_work);
while (1) {
// ... 从 todo 取出 binder_work -> binder_transaction t ...
if (t->buffer->target_node) {
struct binder_node *target_node = t->buffer->target_node;
// 【注释 2】填充 binder_transaction_data:
// - target.ptr = node->ptr(弱引用指针)
// - cookie = node->cookie(BBinder* 指针)
// 注意:这里的 target_node 是 ContentService 的 binder_node,
// 不是 IContentObserver 的 binder_node
// cookie 指向 ContentService 的 JavaBBinder
trd->target.ptr = target_node->ptr;
trd->cookie = target_node->cookie;
binder_transaction_priority(thread, t, target_node);
cmd = BR_TRANSACTION;
}
// 【注释 3】填充事务数据
trd->code = t->code; // 事务码(TRANSACTION_registerContentObserver)
trd->flags = t->flags; // 事务标志
trd->sender_euid = ...;
trd->sender_pid = ...;
// 【注释 4】填充 Parcel 数据指针
// Parcel 中包含经 Binder 驱动翻译后的 IContentObserver flat_binder_object{BINDER_TYPE_HANDLE}
trd->data_size = t->buffer->data_size;
trd->offsets_size = t->buffer->offsets_size;
trd->data.ptr.buffer = t->buffer->user_data;
trd->data.ptr.offsets = ...;
// 【注释 5】将 BR_TRANSACTION 写入用户空间读缓冲区
if (put_user(cmd, (uint32_t __user *)ptr)) { ... }
ptr += sizeof(uint32_t);
// 【注释 6】将 binder_transaction_data 写入用户空间读缓冲区
if (copy_to_user(ptr, &tr, trsize)) { ... }
ptr += trsize;
// ...
}
}
上一节的 binder_thread_read() 注释说"阻塞等待:线程在此睡眠",那它具体是怎么睡的、又是怎么被 App 的 BC_TRANSACTION 叫醒的?这是标准的 Linux 内核**等待队列(waitqueue)**机制,Binder 驱动在"睡眠侧"和"唤醒侧"各做了半件事。用一张图看全景:
Plain
system_server 线程(睡眠侧) App 线程(唤醒侧)
─────────────────────────────────────────────────────────────────────────────
binder_thread_read() ioctl(BC_TRANSACTION)
└─ binder_wait_for_work() └─ binder_transaction()
├─ prepare_to_wait(&thread->wait, ...) └─ binder_proc_transaction()
│ (挂到 thread->wait 等待队列) ├─ binder_select_thread_ilocked()
├─ list_add(&thread->waiting_thread_node, │ (从 proc->waiting_threads
│ &proc->waiting_threads) │ 摘一个等待线程,FIFO)
└─ schedule() ←── 真正睡眠 {调度器切走} ├─ binder_enqueue_thread_work_ilocked()
│ (事务挂到该线程的 todo 队列)
└─ binder_wakeup_thread_ilocked()
└─ wake_up_interruptible(
&thread->wait) ──┐
│
① 被唤醒,从 schedule() 返回 ◄────────────────────────────────────────────┘
② 重新检查 todo 队列 → 有工作 → 跳出循环
③ binder_thread_read 继续执行,取事务 → 投递 BR_TRANSACTION
接收侧:system_server Binder 线程主循环
C++
// frameworks/native/libs/binder/IPCThreadState.cpp:788
void IPCThreadState::joinThreadPool(bool isMain)
{
mProcess->mCurrentThreads++;
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
mIsLooper = true;
status_t result;
do {
processPendingDerefs();
// 【注释 1】核心循环:从 Binder 驱动读取并执行命令
result = getAndExecuteCommand();
// ...
} while (result != -ECONNREFUSED && result != -EBADF);
// ...
}
// frameworks/native/libs/binder/IPCThreadState.cpp:687
status_t IPCThreadState::getAndExecuteCommand()
{
status_t result;
int32_t cmd;
// 【注释 2】与 Binder 驱动交互:ioctl(BINDER_WRITE_READ)
// talkWithDriver 内部调用 ioctl,阻塞等待 BR 命令
result = talkWithDriver();
if (result >= NO_ERROR) {
cmd = mIn.readInt32(); // 读取命令码(如 BR_TRANSACTION)
// 收到 BR_TRANSACTION 后,线程进入"执行 Binder 命令"状态。
// 计数增加发生在 executeCommand() 之前。
size_t newThreadsCount = mProcess->mExecutingThreadsCount.fetch_add(1) + 1;
// 【注释 3】执行命令
// 如果业务方法等待,
// executeCommand() 就不会返回。
result = executeCommand(cmd);
// ...
}
return result;
}
C++
// frameworks/native/libs/binder/IPCThreadState.cpp:1421
case BR_TRANSACTION_SEC_CTX:
case BR_TRANSACTION:
{
binder_transaction_data_secctx tr_secctx;
binder_transaction_data& tr = tr_secctx.transaction_data;
// 【注释 1】从 mIn 读取 binder_transaction_data
// tr.target.ptr = 弱引用指针
// tr.cookie = BBinder 指针(ContentService 的 JavaBBinder*)
// tr.code = 事务码(TRANSACTION_registerContentObserver)
// tr.data.ptr.buffer = Parcel 数据(含 IContentObserver 的 flat_binder_object)
if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
result = mIn.read(&tr_secctx, sizeof(tr_secctx));
} else {
result = mIn.read(&tr, sizeof(tr));
tr_secctx.secctx = 0;
}
// 【注释 2】将 Binder 驱动提供的数据包装为 Parcel
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer);
// 【注释 3】设置调用者身份(Java 层 Binder.getCallingUid/Pid 就是从这读的)
mCallingPid = tr.sender_pid; // App 进程 PID
mCallingUid = tr.sender_euid; // App 进程 EUID
Parcel reply;
status_t error;
if (tr.target.ptr) {
// 【注释 4】核心调用:通过 tr.cookie 获取 BBinder 指针
// tr.cookie 是 ContentService 的 JavaBBinder*
// 先尝试提升弱引用为强引用
if (reinterpret_cast<RefBase::weakref_type*>(
tr.target.ptr)->attemptIncStrong(this)) {
// 【注释 5】调用 BBinder::transact:
// default case -> onTransact() 虚函数
// -> JavaBBinder::onTransact -> env->CallBooleanMethod(execTransact)
// -> Binder.execTransact -> execTransactInternal
// -> IContentService.Stub.onTransact
// -> this.registerContentObserver(uri, ..., observer, ...)
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags);
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
// 【注释 6】恢复调用者身份
mCallingPid = origPid;
mCallingUid = origUid;
// ...
// 【注释 7】非 ONEWAY 事务:发送回复给调用方
// registerContentObserver 是同步调用,走此分支
if ((tr.flags & TF_ONE_WAY) == 0) {
if (error < NO_ERROR) reply.setError(error);
buffer.setDataSize(0);
status_t error2 = sendReply(reply, (tr.flags & kForwardReplyFlags));
// ...
}
}
break;
C++
// frameworks/native/libs/binder/Binder.cpp:374
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
// ...
switch (code) {
case PING_TRANSACTION:
err = pingBinder();
break;
// ... 其他内置事务码省略 ...
default:
// 【注释 1】非内置事务码:调用 onTransact 虚函数
// JavaBBinder override 了 onTransact
// -> env->CallBooleanMethod(mObject, execTransact)
// -> Binder.execTransact -> execTransactInternal
// -> IContentService.Stub.onTransact
// -> 读取参数(含 IContentObserver)-> this.registerContentObserver()
err = onTransact(code, data, reply, flags);
break;
}
return err;
}
JavaBBinder::onTransact 用构造时保存的 GlobalRef 回调 Java
C++
// frameworks/base/core/jni/android_util_Binder.cpp:392
status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
{
JNIEnv* env = javavm_to_jnienv(mVM);
// ...
// 【注释 1】通过 JNI 调用 Java Binder.execTransact
// mObject 是 ContentService(IContentService.Stub)的 GlobalRef
// 这里回调到 ContentService 的 Java 层,最终执行
// IContentService.Stub.onTransact -> this.registerContentObserver()
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;
}
Java
// frameworks/base/core/java/android/os/Binder.java:1346
private boolean execTransact(int code, long dataObj, long replyObj, int flags) {
// 【注释 1】将 Native Parcel 指针包装为 Java Parcel
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
final int callingUid = data.isForRpc() ? -1 : Binder.getCallingUid();
final long origWorkSource = callingUid == -1
? -1 : ThreadLocalWorkSource.setUid(callingUid);
try {
// 【注释 2】委托到 execTransactInternal
return execTransactInternal(code, data, reply, flags, callingUid);
} finally {
reply.recycle();
data.recycle();
// ...
}
}
Java
// frameworks/base/core/java/android/os/Binder.java:1376
private boolean execTransactInternal(int code, Parcel data, Parcel reply, int flags,
int callingUid) {
// ... tracing/observer 省略 ...
try {
// ...
// 【注释 3】调用 onTransact 虚函数:
// this 是 ContentService(IContentService.Stub extends Binder)
// 虚方法分发到 IContentService.Stub.onTransact(AIDL 生成)
// -> 读取参数 -> this.registerContentObserver()
if ((flags & FLAG_COLLECT_NOTED_APP_OPS) != 0 && callingUid != -1) {
AppOpsManager.startNotedAppOpsCollection(callingUid);
try {
res = onTransact(code, data, reply, flags);
} finally {
AppOpsManager.finishNotedAppOpsCollection();
}
} else {
res = onTransact(code, data, reply, flags);
}
} catch (RemoteException|RuntimeException e) {
// ... 异常处理 ...
}
// ...
return res;
}
AIDL 生成的 IContentService.Stub.onTransact 逐个读参数
Java
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
// ...
switch (code) {
case TRANSACTION_registerContentObserver: {
// 【注释 1】读取参数:
Uri _arg0 = ...;
boolean _arg1 = ...;
// 【关键】IContentObserver 通过 readStrongBinder 反扁平化
// readStrongBinder 内部调用 JNI -> unflattenBinder -> getStrongProxyForHandle
// -> BpBinder -> javaObjectForIBinder -> BinderProxy
// 然后 asInterface(BinderProxy) -> queryLocalInterface 返回 null -> new Proxy(BinderProxy)
IContentObserver _arg2 = IContentObserver.Stub.asInterface(
data.readStrongBinder());
int _arg3 = data.readInt();
int _arg4 = data.readInt();
// 【注释 2】调用 ContentService.registerContentObserver
// 此时 _arg2 是 IContentObserver.Stub.Proxy(包装 BinderProxy)
this.registerContentObserver(_arg0, _arg1, _arg2, _arg3, _arg4);
reply.writeNoException();
break;
}
// ...
}
return true;
}
C++
// frameworks/base/core/jni/android_os_Parcel.cpp:515
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
// 【注释 1】parcel->readStrongBinder() 返回 Native sp<IBinder>(BpBinder),
// javaObjectForIBinder 将 BpBinder 包装为 Java BinderProxy
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
cpp
// frameworks/base/core/jni/android_util_Binder.cpp:955
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
// 【注释 1】如果是 JavaBBinder(同进程回环):直接返回原始 Java 对象
// 本场景不是回环,跳过
if (val->checkSubclass(&gBinderOffsets)) {
jobject object = static_cast<JavaBBinder*>(val.get())->object();
return object;
}
// 【注释 2】跨进程场景(本场景):BpBinder 不是 JavaBBinder 子类,
// 创建 BinderProxyNativeData,持有 BpBinder 的强引用
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = sp<DeathRecipientList>::make();
nativeData->mFrozenStateChangeCallbackList = sp<FrozenStateChangeCallbackList>::make();
nativeData->mObject = val; // 【关键】mObject 指向 BpBinder
// 【注释 3】通过 JNI 调用 BinderProxy.getInstance() 创建 Java BinderProxy,
// BinderProxy 内部持有 nativeData -> BpBinder -> handle -> Binder 驱动 binder_ref
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) {
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData != nativeData) {
delete nativeData;
}
return object;
}