从 registerContentObserver 剖析 Android Binder 流程

当你的 App 调用 registerContentObserver() 注册一个观察者时,你的 ContentObserver 明明是 App 进程里的一个 Java 对象,system_server 是怎么把它"持有"在自己进程里的?数据变化时,system_server 又是怎么跨进程"调用"到你这个对象的?

先搞懂几个问题

JavaBBinder:Java Binder 的 Native 层的对象

问题:Transport 已经继承了 android.os.Binder(Java 层),为什么还需要在 Native 层再创建一个 JavaBBinder

答案是它承担了两个无法绕开的核心职责

  1. 作为 Java Binder 的 Native 实体包装JavaBBinder 继承自 BBinder,使 Java Binder 能接入 Native Binder 框架。flat_binder_object 中的 binderJavaBBinderweakRefs 指针,cookieJavaBBinder*;Binder 驱动把两者当作发送进程用户空间的 opaque 标识值,用它们查找或创建 binder_node,而不是解引用并理解 JavaBBinder 对象。

  2. 桥接 Native 回调到 JavaJavaBBinder 通过 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 要完成一次"跨进程变身":

  1. 第一幕(App 进程)ContentObserver 内部的 Transport(继承 IContentObserver.Stub,也就是继承 Binder)作为特殊 Binder 对象被扁平化进 Parcel------Java 对象经过 JNI 层层转换,最终形成一个 flat_binder_object{type=BINDER_TYPE_BINDER} 写进数据缓冲区;

  2. 第二幕(内核) :Binder 驱动发现这个 BINDER_TYPE_BINDER,调用 binder_translate_binder() 把它改写成 BINDER_TYPE_HANDLE,并在两个进程里分别登记实体和引用;

  3. 第三幕(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  │
   └────────────────┘          └──────────────────────────┘        └────────────────┘

三件事:

  1. App 进程侧:binder_node 登记实体(cookie 保存 JavaBBinder 指针------回调的钥匙);

  2. system_server 侧:binder_ref 登记引用,分配句柄(比如 42);

  3. 数据本身: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;
}
相关推荐
Yinlin12433 分钟前
深入悬浮组件实现
前端
yangzheui34 分钟前
nvue页面事件穿透到下层元素解决办法
前端
杉氧35 分钟前
从 Modifier 到 Flexbox:React Native 布局与样式设计哲学
android·前端·react native
比老马还六37 分钟前
Bipes-Blockly项目二次开发/硬件功能-LED灯条(十一)
前端·嵌入式硬件·硬件工程
circuitsosk1 小时前
智能体任务拆解与执行:基于ReAct+Plan-and-Execute框架的行业Skill构建实录
前端·javascript·python·react.js·react·llm agent·智能体编排
daols881 小时前
vue 表格vxe-table 实现紧凑型表格的方式
前端·javascript·vue.js
恋猫de小郭1 小时前
Flutter 多窗口支持类型和 API 介绍
android·前端·flutter
必须会一定会1 小时前
AI 前端项目验收:Playwright 截图、响应式视口、控制台错误与交互回归
前端·人工智能·gpt·交互·ai编程