Binder系列2-ServiceManager

Posted xhBruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Binder系列2-ServiceManager相关的知识,希望对你有一定的参考价值。

Binder系列2-ServiceManager

android12-release

ServiceManager是Binder IPC通信过程中的守护进程,本身也是一个Binder服务。

ServiceManager 其功能:查询和注册服务。 对于Binder IPC通信过程中,其实更多的情形是BpBinder和BBinder之间的通信,比如ActivityManagerProxy和ActivityManagerService之间的通信等。

1. ServiceManager启动

ServiceManager是由init进程通过解析init.rc文件而创建的,其所对应的可执行程序/system/bin/servicemanager,所对应的源文件是service_manager.c,进程名为/system/bin/servicemanager。

与原来的 servicemanager 服务相比较,使用了 libbinder

1.1 servicemanager.rc

  • init进程解析servicemanager.rc,启动调用main.cpp
    frameworks/native/cmds/servicemanager/Android.bp

    frameworks/native/cmds/servicemanager/servicemanager.rc
service servicemanager /system/bin/servicemanager
    class core animation
    user system
    group system readproc
    critical
    onrestart restart apexd
    onrestart restart audioserver
    onrestart restart gatekeeperd
    onrestart class_restart main
    onrestart class_restart hal
    onrestart class_restart early_hal
    writepid /dev/cpuset/system-background/tasks
    shutdown critical

1.2 启动初始化

  • ProcessState::initWithDriver(driver) -> init() -> ProcessState() -> open_driver() -> 初始化/dev/binder
    open(driver, O_RDWR | O_CLOEXEC)打开Binder Driver设备
    ioctl(fd, BINDER_VERSION, &vers) ioctl获取binder版本信息BINDER_VERSION
    ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads) 设置Binder线程最大个数,默认#define DEFAULT_MAX_BINDER_THREADS 15
    ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable) 启用单向SPAM检测
  • mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0) mmap内存映射
  • Access.cpp中selinux_status_open(true) selinux权限启动,用于鉴权
  • manager->addService("manager", manager, ...) 初始化ServiceManager,addService将自身注册到ServiceManager当中
  • IPCThreadState::self()->setTheContextObject(manager)将ServiceManager设置给IPCThreadState的全局变量
  • ps->becomeContextManager() BINDER_SET_CONTEXT_MGR 注册到 Binder Driver,成为上下文的管理者
  • BinderCallback::setupTo(looper) 通知Binder Driver驱动BC_ENTER_LOOPER,LooperCallback监听驱动fd,有消息时回调到handleEvent处理
  • ClientCallbackCallback::setupTo(looper, manager)Client注册监听相关
  • 无限循环等消息,执行looper->pollAll(-1);Android 11 之前是通过binder_loop方法,而现在是通过 looper。

frameworks/native/cmds/servicemanager/main.cpp

int main(int argc, char** argv) 
    if (argc > 2) 
        LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
    

    const char* driver = argc == 2 ? argv[1] : "/dev/binder";

    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    ps->setThreadPoolMaxThreadCount(0);
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);

    sp<ServiceManager> manager = sp<ServiceManager>::make(std::make_unique<Access>());
    if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) 
        LOG(ERROR) << "Could not self register servicemanager";
    

    IPCThreadState::self()->setTheContextObject(manager);
    ps->becomeContextManager();

    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);

    BinderCallback::setupTo(looper);
    ClientCallbackCallback::setupTo(looper, manager);

    while(true) 
        looper->pollAll(-1);
    

    // should not be reached
    return EXIT_FAILURE;

frameworks/native/libs/binder/ProcessState.cpp

static int open_driver(const char *driver)

    int fd = open(driver, O_RDWR | O_CLOEXEC);
    if (fd >= 0) 
        int vers = 0;
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
        if (result == -1) 
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
            close(fd);
            fd = -1;
        
        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) 
          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
            close(fd);
            fd = -1;
        
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (result == -1) 
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        
        uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
        result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
        if (result == -1) 
            ALOGD("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
        
     else 
        ALOGW("Opening '%s' failed: %s\\n", driver, strerror(errno));
    
    return fd;


ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mWaitingForThreads(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)

    if (mDriverFD >= 0) 
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) 
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        
    

#ifdef __ANDROID__
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
#endif

frameworks/native/cmds/servicemanager/Access.cpp

Access::Access() 
    union selinux_callback cb;

    cb.func_audit = auditCallback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);

    cb.func_log = kIsVendor ? selinux_vendor_log_callback : selinux_log_callback;
    selinux_set_callback(SELINUX_CB_LOG, cb);

    CHECK(selinux_status_open(true /*fallback*/) >= 0);

    CHECK(getcon(&mThisProcessContext) == 0);

frameworks/native/cmds/servicemanager/ServiceManager.cpp

ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) 

1.3 时序图

2. 获取defaultServiceManager()

例如media.playerinstatlldBootAnimation进程都使用binder通行,见得比较多的是第三副图BinderService中publish()

2.1 defaultServiceManager()方法

  • std::call_once 处理只需要被调用一次或者初始化一次操作,C++11中提供;该方法就是单例模式。
  • ProcessState::self() 用于获取ProcessState对象(也是单例模式)
  • getContextObject(nullptr)用于获取BpBinder(0)对象
  • interface_cast<AidlServiceManager> 使用IInterface.h模板类获取BpServiceManager对象,sp<AidlServiceManager>等价于 new BpServiceManager(new BpBinder(0))
  • 最终获取IServiceManager.cppgDefaultServiceManager = sp<ServiceManagerShim>::make(sm)

frameworks/native/libs/binder/IServiceManager.cpp

using AidlServiceManager = android::os::IServiceManager;

sp<IServiceManager> defaultServiceManager()

    std::call_once(gSmOnce, []() 
        sp<AidlServiceManager> sm = nullptr;
        while (sm == nullptr) 
            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            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;

2.2 BinderService.h模板interface_cast

  • AidlServiceManager = android::os::IServiceManager带入模板::android::sp<Bp##INTERFACE>::make(obj)实质new BpServiceManager()

frameworks/native/libs/binder/include/binder/BinderService.h

//... ...
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)

    return INTERFACE::asInterface(obj);

//... ...
    static ::android::sp<I##INTERFACE> asInterface(                     \\
            const ::android::sp<::android::IBinder>& obj);              \\
//... ...
    ::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)                                       \\
                intr = ::android::sp<Bp##INTERFACE>::make(obj);         \\
                                                                       \\
                                                                       \\
        return intr;                                                    \\
                                                                       \\

2.3 时序图

3. 注册服务(addService)

3.1 addService客户端

3.1.1 installd通过BinderService注册

  • 通过BinderService注册调用sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags),注册服务"installd"
  • defaultServiceManager()获取BpServiceManager对象
  • ps(ProcessState::self())获得ProcessState实例对象
  • ps->startThreadPool()启动Binder线程池,IPCThreadState::self()->joinThreadPool()当前线程加入到线程池

frameworks/native/cmds/installd/installd.cpp

static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) 
    // ... ...
    if ((ret = InstalldNativeService::start()) != android::OK) 
        SLOGE("Unable to start InstalldNativeService: %d", ret);
        exit(1);
    

    IPCThreadState::self()->joinThreadPool();
    // ... ...

frameworks/native/cmds/installd/InstalldNativeService.cpp

status_t InstalldNativeService::start() 
    IPCThreadState::self()->disableBackgroundScheduling(true);
    status_t ret = BinderService<InstalldNativeService>::publish();
    if (ret != android::OK) 
        return ret;
    
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
    ps->giveThreadPoolName();
    sAppDataIsolationEnabled = android::base::GetBoolProperty(
            kAppDataIsolationEnabledProperty, true);
    return android::OK;

    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) 
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpFlags);
    

3.1.2 SM注册请求

  • mTheRealServiceManager 是android::os::IServiceManager 类型的实例,在 ServiceManagerShim 实例化时赋值。BpServiceManager#addService 方法aidl自动编译生成文件out/.../frameworks/native/libs/binder/libbinder/.../aidl/android/os/IServiceManager.cpp
  • 参照Android 11之前BpServiceManager#addService 实现实质一样的,Parcel数据结构传递
  • Parcel作为接收的数据,其中writeUtf8AsUtf16(name)与Android 11之前不同,有个格式转换
  • BpServiceManager->BpBinder->IPCThreadState->ioctl层层调用后,ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)Binder Driver通信;Binder Driver根据 handle == 0 找到对端 servicemanager 进程,唤醒他开始处理请求

frameworks/native/libs/binder/IServiceManager.cpp

status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                        bool allowIsolated, int dumpsysPriority)

    Status status = mTheRealServiceManager->addService(
        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
    return status.exceptionCode();

Android 11之前BpServiceManager–>BpBinder–>IPCThreadState–>ioctl

frameworks/native/libs/binder/Parcel.cpp

status_t Parcel::writeUtf8AsUtf16(const std::string& str) 
    const uint8_t* strData = (uint8_t*)str.data();
    const size_t strLen= str.length();
    const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
    if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) 
        return BAD_VALUE;
    

    status_t err = writeInt32(utf16Len);
    if (err) 
        return err;
    

    // Allocate enough bytes to hold our converted string and its terminating NULL.
    void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
    if (!dst) 
        return NO_MEMORY;
    

    utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);

    return NO_ERROR;

3.1.3 时序图

3.2 addService服务端

3.2.1 Binder Driver唤醒处理handleEvent()

  • ServiceManager启动中BinderCallback监听,客户端请求Binder Driver唤醒处理handleEvent()
  • handleEvent() -> ... -> executeCommand() -> BBinder#transact -> BnServiceManager#onTransact()最终通过onTransact调用到和Bp端是对称的操作 ServiceManager.cpp::addService 方法
  • BnServiceManager#onTransact()方法也是aidl自动编译生成文件out/.../frameworks/native/libs/binder/libbinder/.../aidl/android/os/IServiceManager.cpp
  • the_context_object
class BinderCallback : public LooperCallback 
public:
    static sp<BinderCallback> setupTo(const sp<Looper>& looper) 
        sp<BinderCallback> cb = sp<BinderCallback>::make();

        int binder_fd = -1;
        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.
    
;

frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::executeCommand(int32_t cmd)

    // ... ...
    case BR_TRANSACT

以上是关于Binder系列2-ServiceManager的主要内容,如果未能解决你的问题,请参考以下文章

Binder系列1-Binder Driver

Binder 系列总结

Binder系列2—Binder Driver再探 - Gityuan博客

Binder 域

Binder 域

Android binder学习一:主要概念