美文网首页
AndroidFramework 之获取 ServiceMana

AndroidFramework 之获取 ServiceMana

作者: 你怕是很皮哦 | 来源:发表于2021-04-14 16:45 被阅读0次

阅读须知

本文源码基于 Android 10,涉及相关源码如下。

frameworks/native/libs/binder/
    - ProcessState.cpp
    - BpBinder.cpp
    - Binder.cpp
    - IServiceManager.cpp
    - Static.cpp

framework/native/include/binder/
    - IServiceManager.h
    - IInterface.h

概述

查询服务和添加服务都需要先通过 defaultServiceManager() 来获取 gDefaultServiceManager,本文将从源码的角度分析这一过程,时序图如下所示。

image.png

1. defaultServiceManager()

来看看 defaultServiceManager() 的源码。

// frameworks/native/libs/binder/Static.cpp

sp<IServiceManager> gDefaultServiceManager;

// frameworks/native/libs/binder/IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()
{
    // 如果 gDefaultServiceManager 存在则直接返回
    if (gDefaultServiceManager != nullptr) return gDefaultServiceManager;
    {
        // 这里用 while 循环。因为尝试获取 ServiceManager 时可能 ServiceManager 未准备就绪,
        while (gDefaultServiceManager == nullptr) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(nullptr));
            if (gDefaultServiceManager == nullptr)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

defaultServiceManager() 采用单例模式,这里之所以用 while 是因为在尝试获取 ServiceManager 时可能 ServiceManager 未准备就绪。

defaultServiceManager() 可以细分为三个步骤:

  1. 调用 ProcessState::self(),获取 ProcessState
  2. 调用 getContextObject(nullptr),获取 BpBinder
  3. 调用 interface_cast<IServiceManager> 获取 BpServiceManager

2. 获取 ProcessState

调用 ProcessState::self() 获取 ProcessState

// frameworks/native/libs/binder/Static.cpp

sp<ProcessState> gProcess;

// frameworks/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::self()
{
    if (gProcess != nullptr) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");
    return gProcess;
}

ProcessState 也是采用单例模式,即每个进程有且只能有一个 ProcessStategProcess 的定义也是在 frameworks/native/libs/binder/Static.cpp,供全局使用。

来看看 ProcessState 的构造器。

// frameworks/native/libs/binder/ProcessState.cpp

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    // 调用 open_driver() 打开 Binder 驱动
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(nullptr)
    , mBinderContextUserData(nullptr)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
    if (mDriverFD >= 0) {
        // 系统调用 mmap() 做内存映射
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
}

ProcessState 构造器主要做了如下两件事:

  1. 调用 open_driver() 打开 Binder 驱动;
  2. 系统调用 mmap() 映射 1M - 8K 的内存空间供进程使用。

2.1 打开 Binder 驱动

ProcessState 先通过 open_driver() 打开 Binder 驱动,这里做了如下事情:

  1. 系统调用 open() 打开 /dev/binder
  2. 系统调用 ioctl() 通过 BINDER_VERSION 获取 Binder 版本并对比版本;
  3. 系统调用 ioctl() 通过 BINDER_SET_MAX_THREADS 设置 Binder 最大线程数。

2.1.1 打开 Binder 驱动

系统调用 open() 打开 /dev/binder

// frameworks/native/libs/binder/ProcessState.cpp

static int open_driver(const char *driver)
{
    // 系统调用 open() 打开 /dev/binder
    int fd = open(driver, O_RDWR | O_CLOEXEC);
}

2.1.2 检查 Binder 版本

系统调用 ioctl() 传入 BINDER_VERSION 获取 Binder 版本并进行版本检查。

// frameworks/native/libs/binder/ProcessState.cpp

static int open_driver(const char *driver)
{
    int vers = 0;
    // 系统调用 ioctl() 通过命令 BINDER_VERSION 获取 Binder 版本
    status_t result = ioctl(fd, BINDER_VERSION, &vers);
    // 版本获取失败
    if (result == -1) {
        close(fd);
        fd = -1;
    }
    // 比对版本
    if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
        close(fd);
        fd = -1;
    }
}

2.1.3 设置 Binder 最大线程数

系统调用 ioctl() 传入 BINDER_SET_MAX_THREADS 设置 Binder 最大线程数。

// frameworks/native/libs/binder/ProcessState.cpp

// Binder 默认最大线程数为 16
#define DEFAULT_MAX_BINDER_THREADS 15

static int open_driver(const char *driver)
{
    // 系统调用 ioctl() 通过命令 BINDER_SET_MAX_THREADS 设置 Binder 最大线程数
    size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
}

2.2 内存映射

系统调用 mmap() 映射 1M - 8K 的内存空间供进程使用。

// frameworks/native/libs/binder/ProcessState.cpp

// mmap() 内存映射大小为 1m - 8k,一页的大小一般为 4k
#define BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)

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)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(nullptr)
    , mBinderContextUserData(nullptr)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
    , mCallRestriction(CallRestriction::NONE)
{
    if (mDriverFD >= 0) {
        // 系统调用 mmap() 做内存映射
        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // 内存映射失败
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
}

内存映射为什么要减少 8K?

其实安卓源码里面最开始这个值的确是 1M,是在后面才减少 8K的,可以看到提交记录如下。

commit c0c1092183ceb38dd4d70d2732dd3a743fefd567
Author: Rebecca Schultz Zavin <rebecca@android.com>
Date:   Fri Oct 30 18:39:55 2009 -0700

    Modify the binder to request 1M - 2 pages instead of 1M.  The backing store
    in the kernel requires a guard page, so 1M allocations fragment memory very
    badly.  Subtracting a couple of pages so that they fit in a power of
    two allows the kernel to make more efficient use of its virtual address space.

    Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com>

diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index d7daf7342..2d4e10ddd 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -41,7 +41,7 @@
 #include <sys/mman.h>
 #include <sys/stat.h>

-#define BINDER_VM_SIZE (1*1024*1024)
+#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

 static bool gSingleProcess = false;

Linux 的内存管理是以页为单位的,一页通常是 4K 的大小,寄存器读取 2^n 内存是最高效的,这么看 1M 似乎没什么问题。但是 Linux 会给内存自动添加一个保护页,如果指定 1M 实际上在加载内存是大于 1M 的,所以这里减去两页大小,每次加载内存时只需要按照 1M 加载就可以了。

3. 获取 BpBinder

来看看 getContextObject() 的源码。

// frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

3.1 getStrongProxyForHandle()

调用 getStrongProxyForHandle() 获取 handle = 0IBinder,那 getStrongProxyForHandle() 做了什么呢?

// frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    // 调用 lookupHandleLocked() 查找 handle = 0 的 handle_entry
    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                Parcel data;
                // 通过ping操作测试 Binder 是否准备就绪
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                if (status == DEAD_OBJECT)
                   return nullptr;
            }
            // 当 handle_entry 存的 IBinder 不存在或弱引用无效时,则创建 BpBinder 对象
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        }
    }

    return result;
}

getStrongProxyForHandle() 先通过 lookupHandleLocked() 查找 handle = 0handle_entry,然后创建 BpBinder 返回。

3.2 lookupHandleLocked()

来看看 lookupHandleLocked() 的源码。

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
{
    const size_t N=mHandleToObject.size();
    // 如果 handle 大于 mHandleToObject 长度,则从 N 开始补 handle+1-N 个 handle_entry
    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;
    }
    // 获取 mHandleToObject 对应位置的 handle_entry
    return &mHandleToObject.editItemAt(handle);
}

struct handle_entry {
    IBinder* binder;
    RefBase::weakref_type* refs;
};

lookupHandleLocked() 会从 mHandleToObject 中查找 handle = 0handle_entry,如果 handle > mHandleToObject.size(),则从 mHandleToObjectN 开始补 handle+1-Nhandle_entry,并返回对应索引的 handle_entry

3.3 创建 BpBinder

调用 BpBinder::create() 创建 BpBinder

// frameworks/native/libs/binder/BpBinder.cpp

BpBinder* BpBinder::create(int32_t handle) {
    return new BpBinder(handle, trackedUid);
}

BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(nullptr)
    , mTrackedUid(trackedUid)
{
    // 延长对象生命周期
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    // handle 所对应的 BpBinder 弱引用 + 1
    IPCThreadState::self()->incWeakHandle(handle, this);
}

4. 获取 BpServiceManager

4.1 interface_cast

调用 interface_cast<IServiceManager>(),这是一个模板函数,其定义在 frameworks/native/libs/binder/include/binder/IInterface.h 中。

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

template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

从定义可知最终调用的是 IServiceManager::asInterface()

4.2 IServiceManager::asInterface()

asInterface() 也是通过模板函数来定义的。

frameworks/native/libs/binder/include/binder/IServiceManager.h 中有如下代码。

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

DECLARE_META_INTERFACE(ServiceManager)

frameworks/native/libs/binder/IServiceManager.cpp 下有如下代码。

// frameworks/native/libs/binder/IServiceManager.cpp

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

DECLARE_META_INTERFACEIMPLEMENT_META_INTERFACE 的声明可以在 frameworks/native/libs/binder/include/binder/IInterface.h 中找到。

4.3 DECLARE_META_INTERFACE

来看看 DECLARE_META_INTERFACE 的声明。

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

#define DECLARE_META_INTERFACE(INTERFACE)                               
    static const ::android::String16 descriptor;    
    static ::android::sp<I##INTERFACE> asInterface(    
            const ::android::sp<::android::IBinder>& obj);  
    virtual const ::android::String16& getInterfaceDescriptor() const; 
    I##INTERFACE(); 
    virtual ~I##INTERFACE();

可以得出 frameworks/native/libs/binder/include/binder/IServiceManager.h 中的 DECLARE_META_INTERFACE(ServiceManager) 实际上对应如下代码。

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

static const ::android::String16 descriptor;    

static ::android::sp<IServiceManager> asInterface(    
        const ::android::sp<::android::IBinder>& obj);  
        
virtual const ::android::String16& getInterfaceDescriptor() const; 

IServiceManager(); 
virtual ~IServiceManager();

即在 IServiceManager.h 中声明了 asInterface()getInterfaceDescriptor()

4.4 IMPLEMENT_META_INTERFACE

来看看 IMPLEMENT_META_INTERFACE 的声明。

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

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)    
    const ::android::String16 I##INTERFACE::descriptor(NAME);  
    const ::android::String16&         
            I##INTERFACE::getInterfaceDescriptor() const {    
        return I##INTERFACE::descriptor;  
    }      
    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface( 
            const ::android::sp<::android::IBinder>& obj) 
    {                
        ::android::sp<I##INTERFACE> intr;  
        if (obj != nullptr) {         
            intr = static_cast<I##INTERFACE*>(    
                obj->queryLocalInterface(          
                        I##INTERFACE::descriptor).get());  
            if (intr == nullptr) {        
                intr = new Bp##INTERFACE(obj);  
            }    
        }           
        return intr;   
    }
    I##INTERFACE::I##INTERFACE() { }
    I##INTERFACE::~I##INTERFACE() { }    

可以得出 frameworks/native/libs/binder/ProcessState.cpp 中的 IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager") 实际上对应如下代码。

// frameworks/native/libs/binder/ProcessState.cpp

const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager");  

const ::android::String16&         
        IServiceManager::getInterfaceDescriptor() const {    
    return IServiceManager::descriptor;  
}      

::android::sp<IServiceManager> IServiceManager::asInterface( 
        const ::android::sp<::android::IBinder>& obj) 
{                
    ::android::sp<IServiceManager> intr;  
    if (obj != nullptr) {         
        intr = static_cast<IServiceManager*>(    
            obj->queryLocalInterface(          
                    IServiceManager::descriptor).get());  
        if (intr == nullptr) {        
            intr = new BpServiceManager(obj);  
        }    
    }           
    return intr;   
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }    

可以看到 IServiceManager::asInterface() 最终会创建 BpServiceManager

4.5 创建 BpServiceManager

4.5.1 BpServiceManager

来看看 BpServiceManager 的实例化过程。

// frameworks/native/libs/binder/IServiceManager.cpp

BpServiceManager(const sp<IBinder>& impl)
    : BpInterface<IServiceManager>(impl)
{
}

4.5.2 BpInterface

BpServiceManager 继承自 BpInterface

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

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

4.5.3 BpRefBase

BpInterface 继承自 BpRefBase

// 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.
    }
}

注意这里的 BpRefBase 在创建时将 mRemote 指向了前面创建的 BpBinder(0),从而 BpServiceManager 能够利用 Binder 进行通信。

至此,获取 ServiceManager 的流程就分析完了。

相关文章

网友评论

      本文标题:AndroidFramework 之获取 ServiceMana

      本文链接:https://www.haomeiwen.com/subject/qyzxlltx.html