AndroidFramework 之获取 ServiceManager

阅读须知

本文源码基于 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 的流程就分析完了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容