frameworks 之ServiceManager


ServiceManager 作为android中的路由器提供服务注册以及查询的功能。本文讲解对应的 启动,以及如何服务端和客户端一个沟通。
涉及到的类如下

  • frameworks/native/cmds/servicemanager/servicemanager.rc
  • frameworks/native/cmds/servicemanager/Android.bp
  • frameworks/native/cmds/servicemanager/main.cpp
  • frameworks/native/cmds/servicemanager/ServiceManager.h
  • frameworks/native/cmds/servicemanager/ServiceManager.cpp
  • frameworks/native/libs/binder/include/binder/IInterface.h
  • frameworks/native/libs/binder/include/binder/Binder.h
  • frameworks/native/libs/binder/include/binder/IBinder.h
  • frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
  • frameworks/native/libs/binder/Android.bp
  • frameworks/native/libs/binder/include/binder/IServiceManager.h
  • frameworks/native/libs/binder/Binder.cpp

解析启动入口

ServiceManager 也是在init解析时候,通过解析 rc 文件启动。对应的 rc 文件详解。可以看到启动名称为 servicemanager 对应执行的脚本为 /system/bin/servicemanager所以 bp 肯定会生成对应的脚本名称为 servicemanager

# frameworks/native/cmds/servicemanager/servicemanager.rc
service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    # 表明这个Service对设备至关重要,如果Service在四分钟内退出超过4次,则设备将重启进入recovery模式
    critical
    # onrestart在重启时执行一条命令
    onrestart restart apexd
    onrestart restart audioserver
    onrestart restart gatekeeperd
    # 重启时,重启class为main、hal、early_hal的所有服务
    onrestart class_restart main
    onrestart class_restart hal
    onrestart class_restart early_hal
    writepid /dev/cpuset/system-background/tasks
    shutdown critical

查看该目录对应的 Bp 文件,根据生成的名称,可以看到启动入口为 main.cpp 。(ServiceManager.cpp和Access.cpp一起生成了servicemanager_defaults,然后通过servicemanager_defaults编译生成可运行的servicemanager.)

# frameworks/native/cmds/servicemanager/Android.bp
cc_defaults {
    name: "servicemanager_defaults",
    ...
    srcs: [
        "Access.cpp",
        "ServiceManager.cpp",
    ],
	...
}
...
cc_binary {
    name: "servicemanager",
    defaults: ["servicemanager_defaults"],
    init_rc: ["servicemanager.rc"],
    srcs: ["main.cpp"],
}

启动

查看对应 main.cpp 的 main 入口。其中会根据是否传参数传驱动节点,因为 rc 文件后面不带参数,所以 driver 值为 /dev/binder。该方法主要作用是

  1. 加载驱动,映射内存,主要在该方法进行 initWithDriver 。该方法的实现可查看 Binder启动 该文章。
  2. 创建 ServiceManager, 并通过 addService 添加自己到服务中。其中 ServiceManager继承BnServiceManager。(在头文件建中继承,该BnServiceManager 通过AIDL生成
  3. 调用 setTheContextObject 设置到 单例 IPCThreadState 中,并且通过 ProcessState的****becomeContextManager 通知驱动设置为标识。
  4. 调用 Looper::prepare 初始化 Looper,并注册对应的回调监听。最后通过 pollAll 开启等待消息。)具体的实现可参看 Looper 文章
// frameworks/native/cmds/servicemanager/main.cpp
int main(int argc, char** argv) {
    if (argc > 2) {
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    }
    // rc 文件没有参数 所以默认为 "/dev/binder"
    const char* driver = argc == 2 ? argv[1] : "/dev/binder";
    // 和binder启动一样 调用 initWithDriver 里面也是调用 init 方法 打开驱动和映射内存大小
    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    // 设置thread poll的最大线程数量
    ps->setThreadPoolMaxThreadCount(0);
    //设置调用限制,FATAL_IF_NOT_ONEWA意思是:在阻塞调用时中止进程
    //oneway 限制,ServiceManager发起的 Binder 调用必须是单向,否则打印堆栈日志提示
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);
    // 实例化ServiceManager, Access为鉴权
    sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
    // 将自己添加到服务中ServiceManager
    if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
        LOG(ERROR) << "Could not self register servicemanager";
    }
    // 创建设置全局变量给IPCThreadState, 并设置 ServiceManager 值给the_context_object
    IPCThreadState::self()->setTheContextObject(manager);
    // 将handle是0注册到binder驱动中
    ps->becomeContextManager();
    // 准备looper
    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);
    // 以前是 binder_loop死 循环接收驱动的消息,现在是 通知驱动BC_ENTER_LOOPER,监听驱动fd,有消息时回调到handleEvent处理binder调用
    // 在looper的 response
    BinderCallback::setupTo(looper);
    // 服务的注册监听相关
    ClientCallbackCallback::setupTo(looper, manager);
    // 无限循环等待消息
    while(true) {
        looper->pollAll(-1);
    }

    // should not be reached
    return EXIT_FAILURE;
}
// frameworks/native/cmds/servicemanager/ServiceManager.h
class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {...}

becomeContextManager 通过 ioctl 跟驱动交互。

bool ProcessState::becomeContextManager()
{
    AutoMutex _l(mLock);

    flat_binder_object obj {
        .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
    };

    int result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);

    // fallback to original method
    if (result != 0) {
        android_errorWriteLog(0x534e4554, "121035042");

        int unused = 0;
        result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &unused);
    }

    if (result == -1) {
        ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
    }

    return result == 0;
}

AIDL实现类

serviceManger 启动后,其他的服务端和客户端跟ServiceManger 不是直接跟 ServiceManger 交互,而是通过Binder驱动 跟 ServiceManger交互
有几个类需要区分,非常重要
如果要创建一个AIDL交互,
需要Server端继承BnInterface, Client端继承BpInterface

BnInterface 在 IInterface.h 中,继承于 BBinder(而BBinder又继承于 IBinder
BpInterface 在 IInterface.h 中,继承于 BpRefBase(而 RefBase 又继承于 RefBase)

// frameworks/native/libs/binder/include/binder/IInterface.h
// 继承于 BBinder
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
    explicit                    BpInterface(const sp<IBinder>& remote);

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

BBinder 代码位于 Binder.h

// frameworks/native/libs/binder/include/binder/Binder.h
class BBinder : public IBinder
{
	...
}

IBinder 位于IBinder.h 中

// frameworks/native/libs/binder/include/binder/IBinder.h
class [[clang::lto_visibility_public]] IBinder : public virtual RefBase
{
	...
}

BpRefBase f位于 Binder.h 中

// frameworks/native/libs/binder/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
	...
}

便于理解 可以总结为 Bp 代表 AIDL 客户端,Bn 代表 AIDL 服务端
在这里插入图片描述
ServiceManger 的 AIDL 位于 frameworks/native/libs/binder/aidl/android/os/文件下,其中IServiceManager.aidl 定义了 addService 等方法。
在这里插入图片描述
对应模块下的 bp 文件定义了对该AIDL的引用

# frameworks/native/libs/binder/Android.bp
cc_library { 
name: "libbinder",
 
// for vndbinder
 
vendor_available: true, vndk: { enabled: true, },
...
    srcs: [
        "Binder.cpp",
        "BpBinder.cpp",
        "IInterface.cpp",
        "IPCThreadState.cpp",
        "IServiceManager.cpp", //对应的cpp文件
...
 
        ":libbinder_aidl",//引用aidl文件
],
    aidl: {//输出aidl头文件
 
        export_aidl_headers: true,
 
    },
},
// AIDL interface between libbinder and framework.jar
filegroup {
    name: "libbinder_aidl",
    srcs: [//aidl文件
        "aidl/android/os/IClientCallback.aidl",
        "aidl/android/os/IServiceCallback.aidl",
        "aidl/android/os/IServiceManager.aidl",
        "aidl/android/os/ServiceDebugInfo.aidl",
    ],
    path: "aidl",
}

其中 IServiceManager.cpp 通过using 关键字定义了别名 AidlServiceManager,提供了 defaultServiceManager 方法。类ServiceManagerShim继承了IServiceManager,Client端的请求都是由ServiceManagerShim 代理类进行调用
AIDL 生成的文件 位于 该目录下out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os。其中 IServiceManager.h, BnServiceManager.h,BpServiceManager.h,为生成了这几个类的头文件。IServiceManager.cpp 则是 BnServiceManager,BpServiceManager 的具体实现。该类主要实现对binder数据的调用。
在这里插入图片描述

客户端Bp发送讲解

正常我们对ServiceManger 添加服务调用 addService 代码如下


sp<ProcessState> proc(ProcessState::self());
//获取B对应BpServiceManager指针
sp<IServiceManager> sm = defaultServiceManager();
 
sp<SimpleManagerService> mService = new SimpleManagerService();
//通过IServiceManager注册服务
sm->addService(String16(NATIVESERVICE_NAME), mService, false);
 
ProcessState::self()->startThreadPool();
// 开启消息监听,不循环 测试程序会结束
IPCThreadState::self()->joinThreadPool();

1. 获取 BpServiceManager

可以看出调用 ServiceManger 第一步是调用 defaultServiceManager 获取对应的对ServiceManger代理对象。
defaultServiceManager 方法如下,部分代码中文说明。

sp<IServiceManager> defaultServiceManager()
{
    std::call_once(gSmOnce, []() {
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) {
            // 拿到客户端BpServiceManager(new BpBinder(0))的实例
            // frameworks/native/libs/binder/include/binder/IInterface.h
            // (interface_cast<IServiceManager>() 等价于 IServiceManager::asInterface(),asInterface是通过模板函数来定义的
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            // 如果为空 serviceManger还没好则循环睡眠1秒
            if (sm == nullptr) {
                ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
                sleep(1);
            }
        }

        gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
    });

    return gDefaultServiceManager;
}

interface_cast 方法需要一个参数,该参数为**BpBInder(0)**对象。具体流程如下,通过调用 getContextObject ,而该方法又会调用 getStrongProxyForHandle 并传入参数为0

// frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
	// 调用 getStrongProxyForHandle 传入参数为0
    sp<IBinder> context = getStrongProxyForHandle(0);
    if (context) {
        // The root object is special since we get it directly from the driver, it is never
        // written by Parcell::writeStrongBinder.
        internal::Stability::markCompilationUnit(context.get());
    } else {
        ALOGW("Not able to get context object on %s.", mDriverName.c_str());
    }
    return context;
}

而 getStrongProxyForHandle 会创建对象并判断 handle 为0 ,继而创建了 BpBInder对象。这很重要。后续将会用到该对象。所以可以说 getContextObject 返回了 BpBinder对象。

// frameworks/native/libs/binder/ProcessState.cpp
ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    // 第一次为空,所以size 等于0, 传进来的参数handle也为0,所以会插入一个实体类为空的
    const size_t N=mHandleToObject.size();
    if (N <= (size_t)handle) {
        handle_entry e;
        e.binder = nullptr;
        e.refs = nullptr;
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
        if (err < NO_ERROR) return nullptr;
    }
    return &mHandleToObject.editItemAt(handle);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    // 会判断是否大于该数字,如果小于则创建
    handle_entry* e = lookupHandleLocked(handle);
    if (e != nullptr) {
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  The
        // attemptIncWeak() is safe because we know the BpBinder destructor will always
        // call expungeHandle(), which acquires the same lock we are holding now.
        // We need to do this because there is a race condition between someone
        // releasing a reference on this BpBinder, and a new reference on its handle
        // arriving from the driver.
        IBinder* b = e->binder;
        // 因为刚插入所以为空
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                // Special case for context manager...
                // The context manager is the only object for which we create
                // a BpBinder proxy without already holding a reference.
                // Perform a dummy transaction to ensure the context manager
                // is registered before we create the first local reference
                // to it (which will occur when creating the BpBinder).
                // If a local reference is created for the BpBinder when the
                // context manager is not present, the driver will fail to
                // provide a reference to the context manager, but the
                // driver API does not return status.
                //
                // Note that this is not race-free if the context manager
                // dies while this code runs.
                //
                // TODO: add a driver API to wait for context manager, or
                // stop special casing handle 0 for context manager and add
                // a driver API to get a handle to the context manager with
                // proper reference counting.

                IPCThreadState* ipc = IPCThreadState::self();

                CallRestriction originalCallRestriction = ipc->getCallRestriction();
                ipc->setCallRestriction(CallRestriction::NONE);

                Parcel data;
                status_t status = ipc->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);

                ipc->setCallRestriction(originalCallRestriction);

                if (status == DEAD_OBJECT)
                   return nullptr;
            }
			// 创建 BpBInder对象
            sp<BpBinder> b = BpBinder::create(handle);
            // 对实体类赋值
            e->binder = b.get();
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

返回了 BpBInder 对象做参数参数,传进去 interface_cast 方法,该方法创建了对象代理对象。interface_cast 方法在 IInterface.h 。采用模板类,类似于java 范型方法。

// frameworks/native/libs/binder/include/binder/IInterface.h
 // 模板类 类似范型
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

而上面调用 interface_cast 传进去的类型为 AidlServiceManager 也即为 IServiceManager 的别名。

// frameworks/native/libs/binder/IServiceManager.cpp
// 定义别名,所以 AidlServiceManager 就是 IServiceManager
using AidlServiceManager = android::os::IServiceManager;

iServiceManger 继承 IInterface, 查看 IInterface 里面的 asInterface 实现和定义

// frameworks/native/libs/binder/include/binder/IServiceManager.h
class IServiceManager : public IInterface { ... }
// frameworks/native/libs/binder/include/binder/IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE)                               \
public:                                                                 \
    ...                     											\
    // 定义了方法
    static ::android::sp<I##INTERFACE> asInterface(                     \
            const ::android::sp<::android::IBinder>& obj);   

可以看到 对应的实现 如果不为空则先进行获取,获取不到则创建对应的对象 可以看到根据对应的模板通过make创建对象, 返回的是 BpServiceManger

#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\
   ... 											                        \
    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
            const ::android::sp<::android::IBinder>& obj)               \
    {                                                                   \
        ::android::sp<I##INTERFACE> intr;                               \
        if (obj != nullptr) {                                           \
            intr = ::android::sp<I##INTERFACE>::cast(                   \
                obj->queryLocalInterface(I##INTERFACE::descriptor));    \
            if (intr == nullptr) {  
                // 通过make 创建带Bp实现类,也则是 BpServiceManger           
                intr = ::android::sp<Bp##INTERFACE>::make(obj);         \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }   

创建代理类 ServiceManagerShim 返回

接下来 通过make参数 创建 ServiceManagerShim代理类 (该类在IServiceManager.cpp)并将上面创建 BpServiceManger 作为参数传进去,查看对应的构造方法。该参数赋值给了 mTheRealServiceManager,所以 mTheRealServiceManager 就是 BpServiceManger

// frameworks/native/libs/binder/IServiceManager.cpp
gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
// 构造方法赋值给了 mTheRealServiceManager
ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
 : mTheRealServiceManager(impl)
{}

所以得到最终 defaultServiceManager 返回的就是 ServiceManagerShim 对象

调用对应AIDL方法

用 addService 为例子,查看 ServiceManagerShim 的实现,可以看到该方法最终是调用 BpServiceManger 的方法。

status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                        bool allowIsolated, int dumpsysPriority)
{
	// mTheRealServiceManager 为  BpServiceManger
    Status status = mTheRealServiceManager->addService(
        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
    return status.exceptionCode();
}

BpServiceManger 是 AIDL生成的,如上面AIDL的讲解以及对应生成路径,BpServiceManger 实现方法逻辑代码 在 IServiceManager.cpp,查看对应的实现方法可以看到 通过 创建 Parcel 实体类作为数据传输。然后通过调用关键代码 remote()->transact 通知驱动

// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/IServiceManager.cpp
::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) {
  ::android::Parcel _aidl_data;
  _aidl_data.markForBinder(remoteStrong());
  ::android::Parcel _aidl_reply;
  ::android::status_t _aidl_ret_status = ::android::OK;
  ::android::binder::Status _aidl_status;
  // 注远程服务名称,getInterfaceDescriptor为远程服务端接口描述
  _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeStrongBinder(service);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeBool(allowIsolated);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_data.writeInt32(dumpPriority);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  // 关键代码, 通过调用 remote()->transact
  _aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_addService, _aidl_data, &_aidl_reply, 0);
  if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IServiceManager::getDefaultImpl())) {
     return IServiceManager::getDefaultImpl()->addService(name, service, allowIsolated, dumpPriority);
  }
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  if (!_aidl_status.isOk()) {
    return _aidl_status;
  }
  _aidl_error:
  _aidl_status.setFromStatusT(_aidl_ret_status);
  return _aidl_status;
}

remote() 返回的是什么对象,查看生成头文件继承自 BpInterface,而 BpInterface 又继承 BpRefBase

// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/BpServiceManager.h
class BpServiceManager : public ::android::BpInterface<IServiceManager> {}

查看 BpRefBase,可以看到该对象又继承 RefBase,可以看到 方法 remote() 返回了 mRemote 对象

// frameworks/native/libs/binder/include/binder/Binder.h
class BpRefBase : public virtual RefBase
{
protected:
    explicit                BpRefBase(const sp<IBinder>& o);
    virtual                 ~BpRefBase();
    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
	// 返回的是 mRemote 对象
    inline IBinder* remote() const { return mRemote; }
    inline sp<IBinder> remoteStrong() const { return sp<IBinder>::fromExisting(mRemote); }

private:
                            BpRefBase(const BpRefBase& o);
    BpRefBase&              operator=(const BpRefBase& o);

    IBinder* const          mRemote;
    RefBase::weakref_type*  mRefs;
    std::atomic<int32_t>    mState;
};

mRemote 又是在 在其构造方法通过参数赋值

// frameworks/native/libs/binder/Binder.cpp
// 通过构造参数传入 
BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(nullptr), mState(0)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);

    if (mRemote) {
        mRemote->incStrong(this);           // Removed on first IncStrong().
        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
    }
}

而因为 BpInterface 继承 BpRefBase 所以又是他将 将入参remote赋值给了BpRefBase

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

而上面 BpServiceManager 继承于BpInterface,所以该参数又来自BpServiceManager的构造参数。而上面调用 interface_cast 创建 BpServiceManager对象的时候,我们又知道 传进去的 就是 BpBinder(0)。 所以可知
remote() 返回的对象就是 BpBinder。所以 remote()->transact 调用的 就是 BpBinder 的 transact方法

调用驱动通知

查看对应 BpBInder transact 方法。最终又会调用 IPCThreadState::self()->transact 方法

// frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        bool privateVendor = flags & FLAG_PRIVATE_VENDOR;
        // don't send userspace flags to the kernel
        flags = flags & ~FLAG_PRIVATE_VENDOR;

        // user transactions require a given stability level
        if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
            using android::internal::Stability;

            auto category = Stability::getCategory(this);
            Stability::Level required = privateVendor ? Stability::VENDOR
                : Stability::getLocalLevel();

            if (CC_UNLIKELY(!Stability::check(category, required))) {
                ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
                    category.debugString().c_str(),
                    String8(getInterfaceDescriptor()).c_str(),
                    Stability::levelString(required).c_str());
                return BAD_TYPE;
            }
        }

        status_t status;
        if (CC_UNLIKELY(isRpcBinder())) {
            status = rpcSession()->transact(rpcAddress(), code, data, reply, flags);
        } else {
        	// //调用 IPCThreadState 方法
            status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
        }

        if (status == DEAD_OBJECT) mAlive = 0;

        return status;
    }

    return DEAD_OBJECT;
}

查看 IPCThreadState 方法 该方法又会调用 writeTransactionData 方法。

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    ....
    LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
        (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
    // 写入数据
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
    ...
        if (reply) {
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
	....
}

进入该方法,通知驱动的数据格式为 binder_transaction_data。所以要创建该实体类,并写入数据,因为是客户端,所以 cmd 为 BC_TRANSACTION

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    binder_transaction_data tr;

    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    tr.target.handle = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        tr.data_size = data.ipcDataSize();
        tr.data.ptr.buffer = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } else if (statusBuffer) {
        tr.flags |= TF_STATUS_CODE;
        *statusBuffer = err;
        tr.data_size = sizeof(status_t);
        tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0;
        tr.data.ptr.offsets = 0;
    } else {
        return (mLastError = err);
    }

    mOut.writeInt32(cmd);
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

waitForResponse 通过 talkWithDriver 方法跟 驱动通信将数据写入到驱动。该方法里面最终调用 ioctl 发送。

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
...     //和Driver通信
        if ((err=talkWithDriver()) < NO_ERROR) break;
...
}

status_t IPCThreadState::talkWithDriver(bool doReceive) {
	...
	if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
	...
}

这样客户端调用完整流程就结束了。

服务端Bn接收讲解

注册Binder回调监听

服务端的接收回到 一开始 main.cpp 注册的Looper监听回调。代码如下 通过 setupTo 方法 添加对应的监听。BinderCallback 主要监听对应的消息进行处理。

// frameworks/native/cmds/servicemanager/main.cpp
class BinderCallback : public LooperCallback {
public:
    static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
        // 实例化BinderCallback
        sp<BinderCallback> cb = sp<BinderCallback>::make();

        int binder_fd = -1;
        //通过IPCThreadState获取binder_fd,即监听binder驱动的消息
        IPCThreadState::self()->setupPolling(&binder_fd);
        LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
        // 添加文件描述符
        int ret = looper->addFd(binder_fd,
                                Looper::POLL_CALLBACK,
                                Looper::EVENT_INPUT,
                                cb,
                                nullptr /*data*/);
        LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");

        return cb;
    }

    int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
        IPCThreadState::self()->handlePolledCommands();
        return 1;  // Continue receiving callbacks.
    }
};

int main(int argc, char** argv) {
    ...
    // 在looper的 response
    BinderCallback::setupTo(looper);
    ...
}

之前说过 Looper 通过 addFd 添加监听,添加对应的 fd 通过 setupPolling 方法获取,进去方法可知 返回的正是驱动FD。所以可知,监听的正在Binder驱动的响应。

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::setupPolling(int* fd)
{
    if (mProcess->mDriverFD < 0) {
        return -EBADF;
    }

    mOut.writeInt32(BC_ENTER_LOOPER);
    flushCommands();
    // 驱动FD
    *fd = mProcess->mDriverFD;
    return 0;
}

Binder消息处理

通过 Looper 文章可知,有消息相应会触发 handleEvent 回调。查看BinderCallback 对应的 handleEvent 方法。而 handleEvent 里面又会调用 handlePolledCommands 方法。

// frameworks/native/cmds/servicemanager/main.cpp
int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
        IPCThreadState::self()->handlePolledCommands();
        return 1;  // Continue receiving callbacks.
    }

查看 handlePolledCommands 又会接着调用 getAndExecuteCommand 方法。

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::handlePolledCommands()
{
    status_t result;

    do {
        result = getAndExecuteCommand();
    } while (mIn.dataPosition() < mIn.dataSize());

    processPendingDerefs();
    flushCommands();
    return result;
}

getAndExecuteCommand 会调用 talkWithDriver 读取对应的对象,并读取对应的cmd值,传进去 executeCommand 进行解析,对应的 cmd 为 BR_TRANSACTION

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;
    //从binder driver获取mIn数据
    result = talkWithDriver();
    if (result >= NO_ERROR) {
    	size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        // 读取出对应 CMD,服务端的应该为 BR_TRANSACTION
        cmd = mIn.readInt32();
        ...
        // 解析出对应的cmd,执行cmd
        result = executeCommand(cmd);
        ...
    }

    return result;
}

查看对应的 executeCommand 方法。查看对应的 BR_TRANSACTION 解析可以看到最终调用了 the_context_object 方法。而 the_context_object 在 ServiceManger 的 main.cpp 方法,可知是通过 setTheContextObject 赋值,所以可知 the_context_object 即为 serviceManger

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::executeCommand(int32_t cmd)
{
...
    switch ((uint32_t)cmd) {
    case BR_TRANSACTION:
        {
...

            } else {
                //sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
                //IPCThreadState::self()->setTheContextObject(manager);//将manager设置给了the_context_object,所以the_context_object就是Server端ServerManager对象
                //调用BBinder的transact
                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
            }
...
}

因为 ServiceManger 继承自 BnServiceManager (AIDL生成)

class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {}

而 BnServiceManager 又继承自 BnInterface

// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/BnServiceManager.h
class BnServiceManager : public ::android::BnInterface<IServiceManager> {}

BnInterface 又是继承 BBinder

// frameworks/native/libs/binder/include/binder/IInterface.h
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    typedef INTERFACE           BaseInterface;
    virtual IBinder*            onAsBinder();
};

所以 the_context_object->transact 也就是调用了 BBinder的 transact 方法。查看对应实现,可发现该方法调用了 onTransact 方法。

// frameworks/native/libs/binder/Binder.cpp
status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);

    if (reply != nullptr && (flags & FLAG_CLEAR_BUF)) {
        reply->markSensitive();
    }

    status_t err = NO_ERROR;
    switch (code) {
        case PING_TRANSACTION:
            err = pingBinder();
            break;
        case EXTENSION_TRANSACTION:
            err = reply->writeStrongBinder(getExtension());
            break;
        case DEBUG_PID_TRANSACTION:
            err = reply->writeInt32(getDebugPid());
            break;
        default:
        	// 调用对应的 onTransact 方法
            err = onTransact(code, data, reply, flags);
            break;
    }

    // In case this is being transacted on in the same process.
    if (reply != nullptr) {
        reply->setDataPosition(0);
    }

    return err;
}

BnServiceManager 实现了 onTransact 方法。 跟BpServiceManager一样,该类的方法实现也在AIDL 生成的 IServiceManager.cpp 里。查看 BnServiceManager 方法,这里举例 addService 方法,可以看到 最终调用了addService(in_name, in_service, in_allowIsolated, in_dumpPriority) 方法。该方法为ServiceManger实现,也就是回调了 ServiceManger类里面的方法

// out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_x86_64_shared/gen/aidl/android/os/IServiceManager.cpp
::android::status_t BnServiceManager::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
  ::android::status_t _aidl_ret_status = ::android::OK;
  switch (_aidl_code) {
  ...
  // 添加的方法
  case BnServiceManager::TRANSACTION_addService:
  {
    ::std::string in_name;
    ::android::sp<::android::IBinder> in_service;
    bool in_allowIsolated;
    int32_t in_dumpPriority;
    if (!(_aidl_data.checkInterface(this))) {
      _aidl_ret_status = ::android::BAD_TYPE;
      break;
    }
    _aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_name);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    _aidl_ret_status = _aidl_data.readStrongBinder(&in_service);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    _aidl_ret_status = _aidl_data.readBool(&in_allowIsolated);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    _aidl_ret_status = _aidl_data.readInt32(&in_dumpPriority);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    // 调用 addService 方法,该方法为ServiceManger实现,也就是回调了 ServiceManger类里面的方法。
    ::android::binder::Status _aidl_status(addService(in_name, in_service, in_allowIsolated, in_dumpPriority));
    _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
    if (((_aidl_ret_status) != (::android::OK))) {
      break;
    }
    if (!_aidl_status.isOk()) {
      break;
    }
  }
  break;
  }
  return _aidl_ret_status;
}
...

ServiceManger 的 addService 方法

// frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
    ...
    // Overwrite the old service if it exists
    mNameToService[name] = Service {
        .binder = binder,
        .allowIsolated = allowIsolated,
        .dumpPriority = dumpPriority,
        .debugPid = ctx.debugPid,
    };
    auto it = mNameToRegistrationCallback.find(name);
    if (it != mNameToRegistrationCallback.end()) {
        for (const sp<IServiceCallback>& cb : it->second) {
            mNameToService[name].guaranteeClient = true;
            // permission checked in registerForNotifications
            cb->onRegistration(name, binder);
        }
    }
    return Status::ok();
}

至此 服务端也接收和处理完对应的Binder消息,实现 客户端到服务端通讯。

备注

在Android的Binder通信机制中,BR_TRANSACTIONBC_TRANSACTION 都是用于定义Binder通信中的消息类型的宏,但它们有着不同的作用和用途。

BR_TRANSACTION 用于定义一个读取操作的IO控制码,表示从用户空间读取数据到内核空间
‘r’ 表示操作的方向,即从用户空间到内核空间的读取操作

BC_TRANSACTION 用于定义一个写入操作的IO控制码,表示从内核空间写入数据到用户空间
‘c’ 表示操作的方向,即从内核空间到用户空间的写入操作

struct binder_transaction_data 是与该IO操作相关联的数据结构,用于描述从内核传递到用户空间的Binder事务的详细信息。

IO控制码类型:_IOR 和 _IOW 分别用于指定读取和写入操作

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值