阅读须知
本文源码基于 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
,本文将从源码的角度分析这一过程,时序图如下所示。
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()
可以细分为三个步骤:
- 调用
ProcessState::self()
,获取ProcessState
; - 调用
getContextObject(nullptr)
,获取BpBinder
; - 调用
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
也是采用单例模式,即每个进程有且只能有一个 ProcessState
,gProcess
的定义也是在 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
构造器主要做了如下两件事:
- 调用
open_driver()
打开Binder
驱动; - 系统调用
mmap()
映射 1M - 8K 的内存空间供进程使用。
2.1 打开 Binder 驱动
ProcessState
先通过 open_driver()
打开 Binder
驱动,这里做了如下事情:
- 系统调用
open()
打开/dev/binder
; - 系统调用
ioctl()
通过BINDER_VERSION
获取Binder
版本并对比版本; - 系统调用
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 = 0
的 IBinder
,那 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 = 0
的 handle_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 = 0
的 handle_entry
,如果 handle > mHandleToObject.size()
,则从 mHandleToObject
的 N
开始补 handle+1-N
个 handle_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_INTERFACE
和 IMPLEMENT_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
的流程就分析完了。
网友评论