Android Binder原理(一)

简介

Binder是基于开源的OpenBinder实现的,OpenBinder最早并不是由Google公司开发的,而是Be Inc公司开发的,接着由Palm, Inc.公司负责开发。后来OpenBinder的作者Dianne Hackborn加入了Google公司,并负责Android平台的开发工作,顺便把这项技术也带进了Android。

Binder是基于内存映射来实现的,在前面我们知道内存映射通常是用在有物理介质的文件系统上的,Binder没有物理介质,它使用内存映射是为了跨进程传递数据。

Binder 原理是掌握系统底层原理的基石。

  • 直观来说,Bindr 是 Android 中的一个类,它实现了 IBinder 接口。
  • 从 IPC 角度来说,是 Android 中的一种跨进程通信方式。
  • 还可以理解为一种虚拟的物理设备,它的设备驱动是 /dev/binder,该通信方式在 Linux 中没有。
  • 从 Android Framework 角度来说,是 ServiceManager 连接各种 Manager 和相应 ManagerService 的桥梁。
  • 从 Android 应用层来说,是客户端和服务端进行通信的媒介,当 bindService 时,服务端会返回一个包含了服务端业务调用的 Binder 对象,通过这个 Binder 对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于 AIDL 的服务。

Binder通信的步骤如下所示。
1.Binder驱动在内核空间创建一个数据接收缓存区。
2.在内核空间开辟一块内核缓存区,建立内核缓存区和数据接收缓存区之间的映射关系,以及数据接收缓存区和接收进程用户空间地址的映射关系。
3.发送方进程通过copy_from_user()函数将数据拷贝 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。

整个过程只使用了1次拷贝,不会因为不知道数据的大小而浪费空间或者时间,效率更高。

Binder 的工作机制:

  • 客户端发起远程请求给 Binder。
  • Binder(内部类 Stub)写入参数(如果有参数)到 data 中。
  • 接着调用 transact 方法发起 RPC(远程过程调用)请求,同时线程被挂起。
  • 然后服务端的 onTransact 方法会被调用,会从 data 中取出目标方法所需参数(如果目标方法有参数),最终向 reply 中写入结果(如果有返回值)。
  • 然后返回数据,唤醒 Client。

Binder 的死亡代理:
Binder 运行在服务端进程,当服务端进程由于某种原因异常终止,这个时候我们到服务端的 Binder 连接断裂(称之为 Binder 死亡),会导致远程调用失败。
可通过 linkToDeath 和 unlinkToDeath 来实现。为 Binder 设置一个死亡代理。

为什么要使用Binder

Android是基于Linux内核的 ,Linux提供了很多IPC机制,而Android却自己设计了Binder来进行通信,主要是因为以下几点。
性能方面
性能方面主要影响的因素是拷贝次数,管道、消息队列、Socket的拷贝次书都是两次,性能不是很好,共享内存不需要拷贝,性能最好,Binder的拷贝次书为1次,性能仅次于内存拷贝。
稳定性方面
Binder是基于C/S架构的,这个架构通常采用两层结构,在技术上已经很成熟了,稳定性是没有问题的。共享内存没有分层,难以控制,并发同步访问临界资源时,可能还会产生死锁。从稳定性的角度讲,Binder是优于共享内存的。
安全方面
Android是一个开源的系统,并且拥有开放性的平台,市场上应用来源很广,因此安全性对于Android 平台而言极其重要。
传统的IPC接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),无法鉴别对方身份。Android 为每个安装好的APP分配了自己的UID,通过进程的UID来鉴别进程身份。另外,Android系统中的Server端会判断UID/PID是否满足访问权限,而对外只暴露Client端,加强了系统的安全性。
语言方面
Linux是基于C语言,C语言是面向过程的,Android应用层和Java Framework是基于Java语言,Java语言是面向对象的。Binder本身符合面向对象的思想,因此作为Android的通信机制更合适不过。

从这四方面来看,Linux提供的大部分IPC机制根本无法和Binder相比较,而共享内存只在性能方面优于Binder,其他方面都劣于Binder,这些就是为什么Android要使用Binder来进行进程间通信,当然系统中并不是所有的进程通信都是采用了Binder,而是根据场景选择最合适的,比如Zygote进程与AMS通信使用的是Socket,Kill Process采用的是信号。

为什么要学习Binder

Binder机制在Android中的地位举足轻重,我们需要掌握的很多原理都和Binder有关:

  1. 系统中的各个进程是如何通信的?
  2. Android系统启动过程
  3. AMS、PMS的原理
  4. 四大组件的原理,比如Activity是如何启动的?
  5. 插件化原理
  6. 系统服务的Client端和Server端是如何通信的?(比如MediaPlayer和MeidaPlayerService)

上面只是列了一小部分,简单来说说,比如系统在启动时,SystemServer进程启动后会创建Binder线程池,目的是通过Binder,使得在SystemServer进程中的服务可以和其他进程进行通信了。再比如我们常说的AMS、PMS都是基于Binder来实现的,拿PMS来说,PMS运行在SystemServer进程,如果它想要和DefaultContainerService通信(是用于检查和复制可移动文件的系统服务),就需要通过Binder,因为DefaultContainerService运行在com.android.defcontainer进程。
还有一个比较常见的C/S架构间通信的问题,Client端的MediaPlayer和Server端的MeidaPlayerService不是运行在一个进程中的,同样需要Binder来实现通信。

可以说Binder机制是掌握系统底层原理的基石。根据Android系统的分层,Binder机制主要分为以下几个部分,其中Java Binder和Native Binder都是应用开发需要掌握的。Java Binder是需要借助Native Binder来工作的,因此需要先了解Native Binder,Native Binder架构的原型就是基于Binder通信的C/S架构。

ServiceManager中的Binder机制

基于Binder通信的C/S架构

在Android系统中,Binder进程间的通信的使用是很普遍的,比如MediaPlayer框架基于C/S架构,并采用Binder来进行进程间通信,如下图所示。

从图中可以看出,除了常规C/S架构的Client端和Server端,还包括了ServiceManager,它用于管理系统中的服务。
首先Server进程会注册一些Service到ServiceManager中,Client要使用某个Service,则需要先到ServiceManager查询Service的相关信息,然后根据Service的相关信息与Service所在的Server进程建立通信通路,这样Client就可以使用Service了。

MediaServer的main函数

Client、Server、ServiceManager三者的交互都是基于Binder通信的,那么任意两者的交互都可以说明Binder的通信的原理,可以说Native Binder的原理的核心就是ServiceManager的原理,为了更好的了解ServiceManager,这里拿MediaPlayer框架来举例,它也是学习多媒体时必须要掌握的知识点。MediaPlayer框架的简单框架图如下所示。

可以看到,MediaPlayer和MediaPlayerService是通过Binder来进行通信的,MediaPlayer是Client端,MediaPlayerService是Server端,MediaPlayerService是系统多媒体服务的一种,系统多媒体服务是由一个叫做MediaServer的服务进程提供的,它是一个可执行程序,在Android系统启动时,MediaServer也被启动,它的入口函数如下所示。main_mediaserver.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
// 获取ProcessState实例,在这一过程中会打开/dev/binder设备,并使用mmap为Binder驱动分配一个虚拟地址空间用来接收数据。
sp<ProcessState> proc(ProcessState::self());
// 用来得到一个IServiceManager,通过这个IServiceManager,其他进程就可以和当前的ServiceManager进行交互,这里就用到了Binder通信。
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
// 注册MediaPlayerService
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
// 启动Binder线程池
ProcessState::self()->startThreadPool();
// 当前线程加入到线程池
IPCThreadState::self()->joinThreadPool();
}

每个进程唯一的ProcessState

ProcessState用于代表进程的状态,在MediaServer的入口函数中调用了ProcessState::self(),查看ProcessState的self函数。ProcessState.cpp

1
2
3
4
5
6
7
8
9
10
11
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
// 这里采用了单例模式,确保每个进程只有一个ProcessState实例。
if (gProcess != NULL) {
return gProcess;
}
// 通过 ProcessState 的构造函数来创建一个 ProcessState 实例,参数为/dev/binder。
gProcess = new ProcessState("/dev/binder");
return gProcess;
}

接着来查看ProcessState的构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
, mDriverFD(open_driver(driver)) // 此函数用来打开/dev/binder设备。
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// mmap函数,它会在内核虚拟地址空间中申请一块与用户虚拟内存相同大小的内存,然后再申请物理内存,将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间,实现了内核虚拟地址空间和用户虚拟内存空间的数据同步操作,也就是内存映射。
// mmap函数用于对Binder设备进行内存映射,除了它还有open、ioctl函数。
mmap函数用于对Binder设备进行内存映射,除了它还有open、ioctl函数,来看看它们做了什么。
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
close(mDriverFD);
mDriverFD = -1;
mDriverName.clear();
}
}
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}

查看打开/dev/binder设备的open_driver函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static int open_driver(const char *driver)
{
// 用于打开/dev/binder设备并返回文件操作符fd,这样就可以操作内核的Binder驱动了。
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd >= 0) {
...
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
// ioctl函数的作用就是和Binder设备进行参数的传递,这里的ioctl函数用于设定binder支持的最大线程数为15(maxThreads的值为15)。
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
} else {
ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
}
// 返回文件操作符fd。
return fd;
}

ProcessState总的来说它做了以下几个重要的事:
1.打开/dev/binder设备并设定Binder最大的支持线程数。
2.通过mmap为binder分配一块虚拟地址空间,达到内存映射的目的。

ServiceManager中的Binder机制

在MediaServer的入口函数中调用了defaultServiceManager函数。IServiceManager.cpp

从IServiceManager所在的文件路径就可以知道,其中不仅仅使用了Binder通信,它自身也是属于Binder体系的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sp<IServiceManager> defaultServiceManager()
{
// 使用了单例
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
// interface_cast函数生成了gDefaultServiceManager,其内部调用了ProcessState的getContextObject函数。
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}

return gDefaultServiceManager;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
// 直接调用了getStrongProxyForHandle函数,注意它的参数的值为0,那么handle的值就为0,handle是一个资源标识。
return getStrongProxyForHandle(0);
}

...

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;

AutoMutex _l(mLock);
// 查询 hanlde 这个资源标识对应的资源(handle_entry)是否存在。
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
Parcel data;
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
// 新建BpBinder,并赋值给 handle_entry 的 binder。
b = BpBinder::create(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
// 最终返回的result的值为BpBinder。
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}

BpBinder和BBinder

它们是Binder通信的“双子星”,都继承了IBinder。BpBinder是Client端与Server交互的代理类,而BBinder则代表了Server端。BpBinder和BBinder是一一对应的,BpBinder会通过handle来找到对应的BBinder。(在ServiceManager中创建了BpBinder,通过handle(值为0)可以找到对应的BBinder。)

回到interface_cast函数,其具体实现如下。IInterface.h

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

当前的场景中,INTERFACE的值为IServiceManager,那么替换后代码如下所示。

1
2
3
4
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj) 
{
return IServiceManager::asInterface(obj);
}

解密IServiceManager

BpBinder和BBinder负责Binder的通信,而 IServiceManager 用于处理 ServiceManager 的业务。IServiceManager.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* IServiceManager 继承了 IInterface,其内部定义了一些常量和一些操作 Service 的函数。
*/
class IServiceManager : public IInterface
{
public:
// 调用了 DECLARE_META_INTERFACE 宏,它的定义在IInterface.h中。
DECLARE_META_INTERFACE(ServiceManager)
... // 一些操作 Service 的函数。
virtual sp<IBinder> getService( const String16& name) const = 0;
virtual sp<IBinder> checkService( const String16& name) const = 0;
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated = false,
int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
};

查看 IInterface.h。IInterface.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#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(); \

// 其中 INTERFACE 的值为 ServiceManager,那么经过替换后的代码如下所示。
#define DECLARE_META_INTERFACE(INTERFACE)
static const ::android::String16 descriptor;
//定义asInterface函数
static ::android::sp<IServiceManager> asInterface(
const ::android::sp<::android::IBinder>& obj);
virtual const ::android::String16& getInterfaceDescriptor() const;
//定义IServiceManager构造函数
IServiceManager();
//定义IServiceManager析构函数
virtual ~IServiceManager();

// 从 DECLARE_META_INTERFACE 宏的名称和上面的代码中,可以发现它主要声明了一些函数和一个变量。那么这些函数和变量的实现在哪呢?答案还是在IInterface.h中,叫做 IMPLEMENT_META_INTERFACE宏,代码如下所示。
#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 != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \

DECLARE_META_INTERFACE 宏和 IMPLEMENT_META_INTERFACE 宏是配合使用的,很多系统服务都使用了它们,IServiceManager 使用 IMPLEMENT_META_INTERFACE 宏只有一行代码,如下所示。

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

IMPLEMENT_META_INTERFACE 宏的 INTERFACE 值为 ServiceManager,NAME 值为 ”android.os.IServiceManager”,进行替换后的代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       
const ::android::String16 IServiceManager::descriptor(”android.os.IServiceManager”);
const ::android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
// 实现了asInterface函数
::android::sp<IServiceManager> IServiceManager::asInterface(
const ::android::sp<::android::IBinder>& obj)
{
::android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
// 新建了一个 BpServiceManager,传入的参数 obj 的值为 BpBinder。
intr = new BpServiceManager(obj);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }

从上面代码可知,asInterface 函数就是用 BpBinder 为参数创建了 BpServiceManager,从而推断出interface_cast 函数创建了BpServiceManager,再往上推断,IServiceManager 的 defaultServiceManager 函数返回的就是 BpServiceManager。BpServiceManager有什么作用呢,先从BpServiceManager的构造函数看起。

1
2
3
4
5
6
7
8
9
10
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
// impl 的值其实就是 BpBinder,BpServiceManager 的构造函数调用了基类 BpInterface的构造函数。
explicit BpServiceManager(const sp<IBinder>& impl)
: BpInterface<IServiceManager>(impl)
{
}
...
};

BpInterface 继承了 BpRefBase,BpRefBase 的实现如下所示。Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
BpRefBase::BpRefBase(const sp<IBinder>& o)
: mRemote(o.get()), mRefs(NULL), mState(0)
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
// mRemote 是一个 IBinder* 指针,它最终的指向为 BpBinder,也就是说 BpServiceManager 的 mRemote 指向了 BpBinder。
// 那么 BpServiceManager 的作用也就知道了,就是它实现了 IServiceManager,并且通过 BpBinder来实现通信。
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
}

IServiceManager家族

1.BpBinder和BBinder都和通信有关,它们都继承自IBinder。
2.BpServiceManager派生自IServiceManager,它们都和业务有关。
3.BpRefBase包含了mRemote,通过不断的派生,BpServiceManager也同样包含mRemote,它指向了BpBinder,通过BpBinder来实现通信。

小节

本篇文章我们学到了Binder通信的C/S架构,也知道了Native Binder的原理的核心其实就是ServiceManager的原理,为了讲解ServiceManager的原理,我们需要一个框架来举例,那就是MediaPlayer框架。在讲解MediaServer的入口函数时,我们遇到了三个问题,其中前两个问题相关的知识点ProcessState和IServiceManager都讲解到了,下一篇文章会讲解第三个问题,MediaPlayerService是如何注册的。

系统服务的注册过程

接下来从调用链角度和进程角度来讲解MediaPlayerService是如何注册的,间接的得出了系统服务是如何注册的
。这里分别对这两个角度做了简化,作为应用开发,我们不需要注重太多的过程和细节,只需要了解大概的步骤即可。

从调用链角度说明MediaPlayerService是如何注册的

先来看MediaServer的入口函数,代码如下所示。main_mediaserver.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
//获取ProcessState实例
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
//注册MediaPlayerService
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
//启动Binder线程池
ProcessState::self()->startThreadPool();
//当前线程加入到线程池
IPCThreadState::self()->joinThreadPool();
}

查看 MediaPlayerService 的 注册过程。MediaPlayerService.cpp

1
2
3
4
5
6
void MediaPlayerService::instantiate() {    
// defaultServiceManager 返回的是 BpServiceManager。
// 参数是一个字符串和MediaPlayerService,看起来像是Key/Value的形式来完成注册。
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}

查看 addService 方法。IServiceManager.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority) {
Parcel data, reply; // data是一个数据包,后面会不断的将数据写入到data中。
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name); // name值为"media.player"
data.writeStrongBinder(service); //service值为MediaPlayerService
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
// remote()指的是mRemote,也就是BpBinder。
// addService函数的作用就是将请求数据打包成data,然后传给BpBinder的transact函数。
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}

查看 transact 函数。BpBinder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
//BpBinder将逻辑处理交给IPCThreadState
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}

return DEAD_OBJECT;
}

查看IPCThreadState::self()。IPCThreadState.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IPCThreadState* IPCThreadState::self()
{
//首次进来gHaveTLS的值为false
if (gHaveTLS) {
restart:
// TLS的全称为Thread local storage,指的是线程本地存储空间,在每个线程中都有TLS,并且线程间不共享。
const pthread_key_t k = gTLS;
// 用于获取TLS中的内容并赋值给IPCThreadState指针。
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
// 会新建一个IPCThreadState,这里可以得知IPCThreadState::self()实际上是为了创建IPCThreadState,
return new IPCThreadState;
}
...
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/** 
* IPCThreadState 的构造函数
*/
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
// pthread_setspecific函数用于设置TLS,将IPCThreadState::self()获得的TLS和自身传进去。
pthread_setspecific(gTLS, this);
clearCaller();
// IPCThreadState中还包含mIn、一个mOut,其中mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节。
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* IPCThreadState 的 transact 函数。
* 调用BpBinder的transact函数实际上就是调用IPCThreadState的transact函数。
*/
status_t IPCThreadState::transact(int32_t handle,uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err;

flags |= TF_ACCEPT_FDS;
...
// writeTransactionData函数用于传输数据,其中第一个参数BCTRANSACTION代表向Binder驱动发送命令协议,向Binder设备发送的命令协议都以BC开头,而Binder驱动返回的命令协议以BR_开头。
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);

if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}

if ((flags & TF_ONE_WAY) == 0) {
...
if (reply) {
// 调用了 waitForResponse 函数
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
...
} else {
//不需要等待reply的分支
err = waitForResponse(NULL, NULL);
}
return err;
}

writeTransactionData函数分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* IPCThreadState 的 writeTransactionData 函数
*/
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结构体)是向Binder驱动通信的数据结构
binder_transaction_data tr;
tr.target.ptr = 0;
// 将handle传递给target的handle,用于标识目标,这里的handle的值为0,代表了ServiceManager。
tr.target.handle = handle;
tr.code = code; //code=ADD_SERVICE_TRANSACTION
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
// 对数据data进行错误检查,如果没有错误就将数据赋值给对应的tr结构体。
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);
}
// 最后会将BC_TRANSACTION和tr结构体写入到mOut中。
mOut.writeInt32(cmd); //cmd=BC_TRANSACTION
mOut.write(&tr, sizeof(tr));

return NO_ERROR;
}

waitForResponse函数分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* IPCThreadState 的 waitForResponse 函数
*/
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_t cmd;
int32_t err;
while (1) {
// talkWithDriver函数的内部通过ioctl与Binder驱动进行通信
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;

cmd = (uint32_t)mIn.readInt32();

IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}

switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;

case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
...
default:
//处理各种命令协议
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
...
return err;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* IPCThreadState 的 talkWithDriver 函数
*/
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
// binder_write_read是和Binder驱动通信的结构体。
binder_write_read bwr;
//mIn是否有可读的数据,接收的数据存储在mIn
const bool needRead = mIn.dataPosition() >= mIn.dataSize();

const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

bwr.write_size = outAvail;
// 将mOut赋值给binder_write_read的相应字段
bwr.write_buffer = (uintptr_t)mOut.data();
//这时doReceive的值为true
if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
// 将mIn赋值给binder_write_read的相应字段
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
...
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;

bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
IF_LOG_COMMANDS() {
alog << "About to read/write, write size = " << mOut.dataSize() << endl;
}
#if defined(__ANDROID__)
//ioctl函数和Binder驱动进行通信,这一部分涉及到Kernel Binder的内容了,就不再详细介绍了,只需要知道在Kernel Binder中会记录服务名和handle,用于后续的服务查询。
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
#else
err = INVALID_OPERATION;
#endif
...
} while (err == -EINTR);
...
return err;
}

小节

从调用链的角度来看,MediaPlayerService是如何注册的貌似并不复杂,因为这里只是简单的介绍了一个调用链分支,可以简单的总结为以下几个步骤:

  1. addService函数将数据打包发送给BpBinder来进行处理。
  2. BpBinder新建一个IPCThreadState对象,并将通信的任务交给IPCThreadState。
  3. IPCThreadState的writeTransactionData函数用于将命令协议和数据写入到mOut中。
  4. IPCThreadState的waitForResponse函数主要做了两件事,一件事是通过ioctl函数操作mOut和mIn来与Binder驱动进行数据交互,另一件事是处理各种命令协议。

从进程角度说明MediaPlayerService是如何注册的

实际上MediaPlayerService的注册还涉及到了进程。

从图中看出是以C/S架构为基础,addService是在MediaPlayerService进行的,它是Client端,用于请求添加系统服务。而Server端则是指的是ServiceManager,用于完成系统服务的添加。
Client端和Server端分别运行在两个进程中,通过向Binder来进行通信。更详细点描述,就是两端通过向Binder驱动发送命令协议来完成系统服务的添加。这其中命令协议非常多,过程也比较复杂,这里对命令协议进行了简化,只涉及到了四个命令协议,其中
BC_TRANSACTION和BR_TRANSACTION过程是一个完整的事务,BC_REPLY和BRREPLY是一个完整的事务。
Client端和Server端向Binder驱动发送命令协议以BC开头,而Binder驱动向Client端和Server端返回的命令协议以BR
开头。

步骤如下所示:
1.Client端向Binder驱动发送BC_TRANSACTION命令。
2.Binder驱动接收到请求后生成BR_TRANSACTION命令,唤醒Server端的线程后将BR_TRANSACTION命令发送给ServiceManager。
3.Server端中的服务注册完成后,生成BC_REPLY命令发送给Binder驱动。
4.Binder驱动生成BR_REPLY命令,唤醒Client端的线程后将BR_REPLY命令发送个Client端。

通过这些协议命令来驱动并完成系统服务的注册。

ServiceManager的启动过程

ServiceManager的启动过程实际上就是分析ServiceManager的入口函数,在入口函数中主要做了三件事。

ServiceManager的入口函数

ServiceManager是init进程负责启动的,具体是在解析init.rc配置文件时启动的,init进程是在系统启动时启动的,因此ServiceManager亦是如此。
rc文件内部由Android初始化语言编写(Android Init Language)编写的脚本,它主要包含五种类型语句:Action、Commands、Services、Options和Import。
在Android 7.0中对init.rc文件进行了拆分,每个服务一个rc文件。ServiceManager的启动脚本在servicemanager.rc中。servicemanager.rc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// service用于通知init进程创建名为servicemanager的进程,这个servicemanager进程执行程序的路径为/system/bin/servicemanager。
service servicemanager /system/bin/servicemanager
class core
//关键字user说明servicemanager是以用户system的身份运行的
user system
group system readproc
//critical说明servicemanager是系统中的关键服务,关键服务是不会退出的,如果退出了,系统就会重启,当系统重启时就会启动用onrestart关键字修饰的进程,比如zygote、media、surfaceflinger等等。
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
writepid /dev/cpuset/system-background/tasks

servicemanager的入口函数在service_manager.c中。service_manager.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int main(int argc, char** argv)
{
// binder_state 结构体用来存储binder的三个信息:
// struct binder_state
//{
// int fd; //binder设备的文件描述符
// void *mapped; //binder设备文件映射到进程的地址空间
// size_t mapsize; //内存映射后,系统分配的地址空间的大小,默认为128KB
//};
struct binder_state *bs;
union selinux_callback cb;
char *driver;

if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}
// 调用binder_open函数用于打开binder设备文件,并申请128k字节大小的内存空间。
bs = binder_open(driver, 128*1024);
...
// 调用binder_become_context_manager函数,将servicemanager注册成为Binder机制的上下文管理者
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
...
if (getcon(&service_manager_context) != 0) {
ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
abort();
}
// 调用binder_loop函数,循环等待和处理client端发来的请求。
binder_loop(bs, svcmgr_handler);
return 0;
}

打开binder设备

binder_open函数用于打开binder设备文件,并且将它映射到进程的地址空间,如下所示。binder.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
struct binder_state *bs;
struct binder_version vers;

bs = malloc(sizeof(*bs));
if (!bs) {
errno = ENOMEM;
return NULL;
}
// 打开binder设备文件
// open函数,它会调用Kernel Binder部分的binder_open函数,这部分源码位于内核源码中,这里展示的代码版本为goldfish3.4。
bs->fd = open(driver, O_RDWR | O_CLOEXEC);
if (bs->fd < 0) {
fprintf(stderr,"binder: cannot open %s (%s)\n",
driver, strerror(errno));
goto fail_open;
}
// ioctl函数用于获取Binder的版本,如果获取不到或者内核空间和用户空间的binder不是同一个版本就会直接goto到fail_open标签,释放binder的内存空间。
if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
(vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
fprintf(stderr,
"binder: kernel driver version (%d) differs from user space version (%d)\n",
vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
goto fail_open;
}

bs->mapsize = mapsize;
// 调用mmap函数进行内存映射,通俗来讲就是将binder设备文件映射到进程的地址空间,地址空间的大小为mapsize,也就是128K。映射完毕后会将地址空间的起始地址和大小保存在binder_state结构体中的mapped和mapsize变量中。
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
if (bs->mapped == MAP_FAILED) {
fprintf(stderr,"binder: cannot map device (%s)\n",
strerror(errno));
goto fail_map;
}

return bs;

fail_map:
close(bs->fd);
fail_open:
free(bs);
return NULL;
}

用户态和内核态
临时插入一个知识点:用户态和内核态
Intel的X86架构的CPU提供了0到3四个特权级,数字越小,权限越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态与用户态。用户态的特权级别低,因此进程在用户态下不经过系统调用是无法主动访问到内核空间中的数据的,这样用户无法随意的进入所有进程共享的内核空间,起到了保护的作用。下面来介绍下什么是用户态和内核态。
当一个进程在执行用户自己的代码时处于用户态,比如open函数,它运行在用户空间,当前的进程处于用户态。
当一个进程因为系统调用进入内核代码中执行时就处于内核态,比如open函数通过系统调用(__open()函数),查找到了open函数在Kernel Binder对应的函数为binder_open,这时binder_open运行在内核空间,当前的进程由用户态切换到内核态。

kernel/goldfish/drivers/staging/android/binder.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
static int binder_open(struct inode *nodp, struct file *filp)
{
//binder_proc结构体代表binder进程,用于管理binder的各种信息。
struct binder_proc *proc;
binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
current->group_leader->pid, current->pid);
//为binder_proc分配内存空间。
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
if (proc == NULL)
return -ENOMEM;
get_task_struct(current);
proc->tsk = current;
INIT_LIST_HEAD(&proc->todo);
init_waitqueue_head(&proc->wait);
proc->default_priority = task_nice(current);
//binder同步锁
binder_lock(__func__);

binder_stats_created(BINDER_STAT_PROC);
hlist_add_head(&proc->proc_node, &binder_procs);
proc->pid = current->group_leader->pid;
INIT_LIST_HEAD(&proc->delivered_death);
// 将binder_proc赋值给file指针的private_data变量
filp->private_data = proc;
//binder同步锁释放
binder_unlock(__func__);
...
return 0;
}

注册成为Binder机制的上下文管理者

binder_become_context_manager函数用于将servicemanager注册成为Binder机制的上下文管理者,这个管理者在整个系统只有一个,代码如下所示。binder.c

1
2
3
4
5
int binder_become_context_manager(struct binder_state *bs)
{
// ioctl函数会调用Binder驱动的binder_ioctl函数
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

binder_ioctl函数代码比较多,这里截取BINDER_SET_CONTEXT_MGR的处理部分,代码如下所示。
kernel/goldfish/drivers/staging/android/binder.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
// 将file指针中的private_data变量赋值给binder_proc,这个private_data变量在binder_open函数中讲过,是一个binder_proc结构体。
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
unsigned int size = _IOC_SIZE(cmd);
void __user *ubuf = (void __user *)arg;
trace_binder_ioctl(cmd, arg);

ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret)
goto err_unlocked;

binder_lock(__func__);
// binder_get_thread函数用于获取binder_thread,binder_thread结构体指的是binder线程,binder_get_thread函数内部会从传入的参数binder_proc中查找binder_thread,如果查询到直接返回,如果查询不到会创建一个新的binder_thread并返回。
thread = binder_get_thread(proc);
if (thread == NULL) {
ret = -ENOMEM;
goto err;
}

switch (cmd) {
...
case BINDER_SET_CONTEXT_MGR:
// 全局变量binder_context_mgr_node代表的是Binder机制的上下文管理者对应的一个Binder对象,如果它不为NULL,说明此前自身已经被注册为Binder的上下文管理者了,Binder的上下文管理者是不能重复注册的,因此会goto到err标签。
if (binder_context_mgr_node != NULL) {
printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
ret = -EBUSY;
goto err;
}
ret = security_binder_set_context_mgr(proc->tsk);
if (ret < 0)
goto err;
// 全局变量binder_context_mgr_uid代表注册了Binder机制上下文管理者的进程的有效用户ID,如果它的值不为-1,说明此前已经有进程注册Binder的上下文管理者了。
if (binder_context_mgr_uid != -1) {
// 判断当前进程的有效用户ID是否等于binder_context_mgr_uid,不等于就goto到err标签。
if (binder_context_mgr_uid != current->cred->euid) {
printk(KERN_ERR "binder: BINDER_SET_"
"CONTEXT_MGR bad uid %d != %d\n",
current->cred->euid,
binder_context_mgr_uid);
ret = -EPERM;
goto err;
}
} else
// 如果不满足判断条件,说明此前没有进程注册Binder机制的上下文管理者。
// 将当前进程的有效用户ID赋值给全局变量binder_context_mgr_uid。
binder_context_mgr_uid = current->cred->euid;
// 调用binder_new_node函数创建一个Binder对象并赋值给全局变量binder_context_mgr_node。
binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
if (binder_context_mgr_node == NULL) {
ret = -ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;
break;
...
err_unlocked:
trace_binder_ioctl_done(ret);
return ret;
}

循环等待和处理client端发来的请求

servicemanager成功注册成为Binder机制的上下文管理者后,servicemanager就是Binder机制的“总管”了,它需要在系统运行期间处理client端的请求,由于client端的请求不确定何时发送,因此需要通过无限循环来实现,实现这一需求的函数就是binder_loop。binder.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
uint32_t readbuf[32];

bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;

readbuf[0] = BC_ENTER_LOOPER;
// 将BC_ENTER_LOOPER指令通过binder_write函数写入到Binder驱动中,这样当前线程(ServiceManager的主线程)就成为了一个Binder线程,这样就可以处理进程间的请求了。
binder_write(bs, readbuf, sizeof(uint32_t));

for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
// 在无限循环中不断的调用ioctl函数,它不断的使用BINDER_WRITE_READ指令查询Binder驱动中是否有新的请求,
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

if (res < 0) {
ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
break;
}
// 如果有新的请求就交给binder_parse函数处理。如果没有,当前线程就会在Binder驱动中睡眠,等待新的进程间请求。
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
if (res == 0) {
ALOGE("binder_loop: unexpected reply?!\n");
break;
}
if (res < 0) {
ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
break;
}
}
}

由于binder_write函数的调用链中涉及到了内核空间和用户空间的交互,因此这里着重讲解下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int binder_write(struct binder_state *bs, void *data, size_t len)
{
// 定义binder_write_read结构体
struct binder_write_read bwr;
int res;
// 对bwr进行赋值
bwr.write_size = len;
bwr.write_consumed = 0;
// data的值为BC_ENTER_LOOPER
bwr.write_buffer = (uintptr_t) data;
bwr.read_size = 0;
bwr.read_consumed = 0;
bwr.read_buffer = 0;
// ioctl函数将会bwr中的数据发送给binder驱动。
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
fprintf(stderr,"binder_write: ioctl failed (%s)\n",
strerror(errno));
}
return res;
}

ioctl函数在Kernel Binder中对应的函数为binder_ioctl,此前分析过这个函数,这里截取BINDER_WRITE_READ命令处理部分。

kernel/goldfish/drivers/staging/android/binder.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
...
void __user *ubuf = (void __user *)arg;
...
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
if (size != sizeof(struct binder_write_read)) {
ret = -EINVAL;
goto err;
}
// copy_from_user函数,在这里,它用于将把用户空间数据ubuf拷贝出来保存到内核数据bwr(binder_write_read结构体)中。
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
binder_debug(BINDER_DEBUG_READ_WRITE,
"binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
bwr.read_size, bwr.read_buffer);

if (bwr.write_size > 0) {
// bwr的输入缓存区有数据时,会调用binder_thread_write函数来处理BC_ENTER_LOOPER协议,其内部会将目标线程的状态设置为BINDER_LOOPER_STATE_ENTERED,这样目标线程就是一个Binder线程。
ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
trace_binder_write_done(ret);
if (ret < 0) {
bwr.read_consumed = 0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
...
binder_debug(BINDER_DEBUG_READ_WRITE,
"binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
bwr.read_consumed, bwr.read_size);
//通过copy_to_user函数将内核空间数据bwr拷贝到用户空间。
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret = -EFAULT;
goto err;
}
break;
}
...
return ret;
}

系统服务的获取过程

此前以MediaPlayerService为例,讲解了系统服务是如何注册的(addService),既然有注册那肯定也要有获取,仍旧以MediaPlayerService为例,来讲解系统服务的获取过程(getService)。会分为两个部分进行讲解,分别是客户端MediaPlayerService请求获取服务和服务端ServiceManager处理请求。

客户端MediaPlayerService请求获取服务

要想获取MediaPlayerService,需要先调用getMediaPlayerService函数,如下所示。IMediaDeathNotifier.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
// defaultServiceManager返回的是BpServiceManager
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
// 获取名为”media.player”的系统服务(MediaPlayerService),返回的值为BpBinder。
binder = sm->getService(String16("media.player"));
// 由于这个时候MediaPlayerService可能还没有向ServiceManager注册,那么就不能满足条件。
if (binder != 0) {
break;
}
ALOGW("Media player service not published, waiting...");
// 休眠0.5s后继续调用getService函数,直到获取服务对应的为止。
usleep(500000); // 0.5 s
} while (true);

if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
// interface_cast函数用于将BpBinder转换成BpMediaPlayerService,其原理就是通过BpBinder的handle来找到对应的服务,即BpMediaPlayerService。
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}

获取服务是重点,BpServiceManager的getService函数如下所示。IServiceManager.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class BpServiceManager : public BpInterface<IServiceManager>
{
...
virtual sp<IBinder> getService(const String16& name) const
{
...
int n = 0;
while (uptimeMillis() < timeout) {
n++;
if (isVendorService) {
ALOGI("Waiting for vendor service %s...", String8(name).string());
CallStack stack(LOG_TAG);
} else if (n%10 == 0) {
ALOGI("Waiting for service %s...", String8(name).string());
}
usleep(1000*sleepTime);

sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
}
ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
return NULL;
}
...
};

getService函数中主要做的事就是循环的查询服务是否存在,如果不存在就继续查询,查询服务用到了checkService函数,代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class BpServiceManager : public BpInterface<IServiceManager>
{
...
virtual sp<IBinder> checkService( const String16& name) const
{
// data,此前它出现在BpServiceManager的addService函数中,data是一个数据包,后面会不断的将数据写入到data中。
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
// 将字符串”media.player”写入到data中。
data.writeString16(name);
// remote()指的是mRemote,也就是BpBinder。
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();
}
...
};

BpBinder的transact函数如下所示。BpBinder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}

return DEAD_OBJECT;
}

BpBinder 将逻辑处理交给 IPCThreadState,后面的调用链在此前的系统服务的注册过程中有讲,最后会调用到talkWithDriver函数,其内部通过ioctl与Binder驱动进行通信。

当前分析的是客户端进程的流程,当MediaPlayerService向Binder驱动发送BC_TRANSACTION命令后,Binder驱动会向ServiceManager发送BR_TRANSACTION命令,接下来查看服务端ServiceManager是如何处理获取服务这一请求的。

服务端ServiceManager处理请求

说到服务端ServiceManager处理请求,不得不说到ServiceManager的启动过程,在 servicemanager 的入口 man 函数中主要做了三件事,其中最后一件事就是调用binder_loop函数,这里需要注意,它的第二个参数为svcmgr_handler。

binder_loop函数在无限循环中不断的调用ioctl函数,它不断的使用BINDER_WRITE_READ指令查询Binder驱动中是否有新的请求,如果有就交给binder_parse函数处理。如果没有,当前线程就会在Binder驱动中睡眠,等待新的进程间通信请求。binder_parse函数如下所示。binder.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
int binder_parse(struct binder_state *bs, struct binder_io *bio,
uintptr_t ptr, size_t size, binder_handler func)
{
int r = 1;
uintptr_t end = ptr + (uintptr_t) size;

while (ptr < end) {
uint32_t cmd = *(uint32_t *) ptr;
ptr += sizeof(uint32_t);
#if TRACE
fprintf(stderr,"%s:\n", cmd_name(cmd));
#endif
switch(cmd) {
...
// 这里截取了BR_TRANSACTION命令的处理部分。
case BR_TRANSACTION: {
struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
if ((end - ptr) < sizeof(*txn)) {
ALOGE("parse: txn too small!\n");
return -1;
}
binder_dump_txn(txn);
if (func) {
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;

bio_init(&reply, rdata, sizeof(rdata), 4);
bio_init_from_txn(&msg, txn);
// func通过一路传递指向的是 svcmgr_handler
res = func(bs, txn, &msg, &reply);
if (txn->flags & TF_ONE_WAY) {
binder_free_buffer(bs, txn->data.ptr.buffer);
} else {
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
}
}
ptr += sizeof(*txn);
break;
}
...
}
return r;
}

查看 svcmgr_handler 。 service_manager.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
...
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;

...
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}

bio_put_uint32(reply, 0);
return 0;
}

当要获取服务时,会调用do_find_service函数,代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
{
// find_svc函数用于查询服务,返回的svcinfo是一个结构体,其内部包含了服务的handle值。
struct svcinfo *si = find_svc(s, len);//1

if (!si || !si->handle) {
return 0;
}

if (!si->allow_isolated) {
uid_t appid = uid % AID_USER;
if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
return 0;
}
}
if (!svc_can_find(s, len, spid, uid)) {
return 0;
}
// 最终会返回服务的handle值。
return si->handle;
}

接着看find_svc函数。

1
2
3
4
5
6
7
8
9
10
11
12
struct svcinfo *find_svc(const uint16_t *s16, size_t len)
{
struct svcinfo *si;

for (si = svclist; si; si = si->next) {
if ((len == si->len) &&
!memcmp(s16, si->name, len * sizeof(uint16_t))) {
return si;
}
}
return NULL;
}

系统服务的注册流程中,在Kernel Binder中会调用do_add_service函数,其内部会将包含服务名和handle值的svcinfo保存到svclist列表中。同样的,在获取服务的流程中,find_svc函数中会遍历svclist列表,根据服务名查找对应服务是否已经注册,如果已经注册就会返回对应的svcinfo,如果没有注册就返回NULL。

Java Binder的初始化

此前都在介绍Native Binder和Kernel Binder的内容,它们的架构简单总结为下图。

在ServiceManager中的Binder机制中,知道BpBinder是Client端与Server交互的代理类,而BBinder则代表了Server端,那么上图就可以改为:

从上图可以看到,Native Binder实际是基于C/S架构,Bpinder是Client端,BBinder是Server端,在ServiceManager的启动过程中,得知Native Binder通过ioctl函数和Binder驱动进行数据交互。

Java Binder是需要借助Native Binder来进行工作的,因此Java Binder在设计上也是一个C/S架构,可以说Java Binder是Native Binder的一个镜像,接下来看 Java Binder 是如何初始化的,即Java Binder的JNI注册。

Java Binder的JNI注册

Java Binder要想和Native Binder进行通信,需要通过JNI,JNI的注册是在Zygote进程启动过程中注册的,代码如下所示。AndroidRuntime.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 启动Java虚拟机
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
// startReg 函数用于完成虚拟机的JNI注册
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
}

startReg函数如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
ATRACE_NAME("RegisterAndroidNatives");
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

ALOGV("--- registering native functions ---\n");
env->PushLocalFrame(200);

if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL);
return 0;
}

register_jni_procs函数的作用就是循环调用gRegJNI数组的成员所对应的方法,如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
for (size_t i = 0; i < count; i++) {
if (array[i].mProc(env) < 0) {
#ifndef NDEBUG
ALOGD("----------!!! %s failed to load\n", array[i].mName);
#endif
return -1;
}
}
return 0;
}

gRegJNI数组中有100多个成员变量:

1
2
3
4
5
6
7
8
9
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
...
// register_android_os_Binder 函数负责Java Binder和Native Binder通信。
REG_JNI(register_android_os_Binder),
...
};

其中REG_JNI是一个宏定义,实际上就是调用参数名所对应的函数。

1
2
3
4
#define REG_JNI(name)      { name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
};

查看 register_android_os_Binder 函数,它做了如下三件事。android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int register_android_os_Binder(JNIEnv* env)
{
//注册Binder类
if (int_register_android_os_Binder(env) < 0)
return -1;
//注册BinderInternal类
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
//注册BinderProxy类
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
...
return 0;
}

它们是Java Binder关联类的一小部分,它们的关系如下。

  • IBinder接口中定义了很多整型的变量,其中定义一个叫做FLAG_ONEWAY的整形变量。客户端发起调用时,客户端一般会阻塞,直到服务端返回结果。设置FLAG_ONEWAY后,客户端只需要把请求发送到服务端就可以立即返回,而不需要等待服务端的结果,这是一种非阻塞方式。
  • Binder和BinderProxy实现了IBinder接口,Binder是服务端的代表,而BinderProxy是客户端的代表。
  • BinderInternal只是在Binder框架中被使用,其内部类GcWatcher用于处理和Binder的垃圾回收。
  • Parcel是一个数据包装器,它可以在进程间进行传递,Parcel既可以传递基本数据类型也可以传递Binder对象,Binder通信就是通过Parcel来进行客户端与服务端数据交互。Parcel的实现既有Java部分,也有Native部分,具体实现在Native部分中。

下面分别对Binder、BinderInternal这两个类的注册进行分析。

Binder类的注册

调用int_register_android_os_Binder函数来完成Binder类的注册,代码如下所示。android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
{ "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
// kBinderPathName的值为”android/os/Binder”,这是Binder在Java Binder中的全路径名。
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
// 根据路径名获取Binder的Class对象,并赋值给jclass类型的变量clazz,clazz是Java层Binder在JNI层的代表。
jclass clazz = FindClassOrDie(env, kBinderPathName);
// 通过MakeGlobalRefOrDie函数将本地引用clazz转变为全局引用并赋值给gBinderOffsets.mClass。
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
// 用于找到Java层的Binder的成员方法execTransact并赋值给gBinderOffsets.mExecTransact。
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
// 用于找到Java层的Binder的成员变量mObject并赋值给gBinderOffsets.mObject。
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
// 通过RegisterMethodsOrDie函数注册gBinderMethods中定义的函数,其中gBinderMethods是JNINativeMethod类型的数组,里面存储的是Binder的Native方法(Java层)与JNI层函数的对应关系。
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}

gBinderMethods的定义如下所示。

1
2
3
4
5
6
7
static struct bindernative_offsets_t
{
jclass mClass;
jmethodID mExecTransact;
jfieldID mObject;

} gBinderOffsets;

使用gBinderMethods来保存变量和方法有两个原因:
1.为了效率考虑,如果每次调用相关的方法时都需要查询方法和变量,显然效率比较低。
2.这些成员变量和方法都是本地引用,在int int_register_android_os_Binder函数返回时,这些本地引用会被自动释放,因此用gBinderOffsets来保存,以便于后续使用。

BinderInternal类的注册

调用int_register_android_os_BinderInternal函数来完成BinderInternal类的注册,代码如下所示。android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");

jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
"<init>", "()V");
gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
"(II)V");

BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);

return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

和int_register_android_os_Binder函数的实现类似,主要做了三件事:
1.获取BinderInternal在JNI层的代表clazz。
2.将BinderInternal类中有用的成员变量和方法存储到gBinderInternalOffsets中。
3.注册BinderInternal类的Native方法对应的JNI函数。

BinderProxy类的注册

它和Binder、BinderInternal的注册过程差不多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
"(JJ)Landroid/os/BinderProxy;");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo",
"()V");
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");

clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

Java Binder中系统服务的注册过程

在系统服务的注册过程中,介绍的是Native Binder中的系统服务的注册过程,这一过程的核心是ServiceManager,而在Java Binder中,也有一个ServiceManager,只不过这个ServiceManager是Java文件。
既然要将系统服务注册到ServiceManager,那么需要选择一个系统服务为例,这里以常见的AMS为例。

将AMS注册到ServiceManager

在AMS的setSystemProcess方法中,会调用ServiceManager的addService方法,如下所示。ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
public void setSystemProcess() {
try {
// Context.ACTIVITY_SERVICE 的值为”activity”,作用就是将AMS注册到ServiceManager中。
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
....
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
...
}

接着看ServiceManager的addService方法。ServiceManager.java

1
2
3
4
5
6
7
8
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}

主要分析getIServiceManager方法返回的是什么,代码如下所示。

1
2
3
4
5
6
7
8
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}

讲到这里,已经积累了几个点需要分析,分别是:

  • BinderInternal.getContextObject()
  • ServiceManagerNative.asInterface()
  • getIServiceManager().addService()

BinderInternal.getContextObject()

Binder.allowBlocking的作用是将BinderProxy的sWarnOnBlocking值置为false。主要来分析BinderInternal.getContextObject()做了什么,这个方法是一个Native方法,找到它对应的函数:android_util_Binder.cpp

1
2
3
4
static const JNINativeMethod gBinderInternalMethods[] = {
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
...
};

对应的函数为android_os_BinderInternal_getContextObject:

1
2
3
4
5
6
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
// 最终返回的是BpBinder
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}

ProcessState::self()的作用是创建ProcessState。

BpBinder是Native Binder中的Client端,这说明Java层的ServiceManager需要Native层的BpBinder,但是这个BpBinder在Java层是无法直接使用,那么就需要传入javaObjectForIBinder函数来做处理,其内部会创建一个BinderProxy对象(BinderProxy是Java Binder的客户端的代表),这样我们得知 BinderInternal.getContextObject()最终得到的是BinderProxy。
需要注意的一点是,这个传入的BpBinder会保存到BinderProxy的成员变量mObject中。

ServiceManagerNative.asInterface()

说到asInterface方法,在Native Binder中也有一个asInterface函数,IServiceManager的asInterface函数,它的作用是用BpBinder做为参数创建BpServiceManager。那么在Java Binder中的asInterface方法的作用又是什么?ServiceManagerNative.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// asInterface方法的作用就是用BinderProxy作为参数创建ServiceManagerProxy。
static public IServiceManager asInterface(IBinder obj)
{
// obj的值为BinderProxy
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}

return new ServiceManagerProxy(obj);
}

BinderProxy和BpBinder分别在Jave Binder和Native Binder作为客户端的代表,BpServiceManager通过BpBinder来实现通信,同样的,ServiceManagerProxy也会将业务的请求交给BinderProxy来处理。
分析到这里,那么:

1
2
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));

可以理解为:

1
2
    sServiceManager = new ServiceManagerProxy(BinderProxy);
}

getIServiceManager().addService()

getIServiceManager()返回的是ServiceManagerProxy,ServiceManagerProxy是ServiceManagerNative的内部类,它实现了IServiceManager接口。来查看ServiceManagerProxy的addService方法。ServiceManagerNative.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* ServiceManagerProxy 类的 addService 方法
*/
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
throws RemoteException {
// Parcel,它是一个数据包装器,将请求数据写入到Parcel类型的对象data中。
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
// 这里很关键
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
data.writeInt(dumpPriority);
// 通过mRemote.transact将 Parcel 发送出去,mRemote实际上是BinderProxy。
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}

BinderProxy.transact是native函数,实现的函数如下所示。android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
if (dataObj == NULL) {
jniThrowNullPointerException(env, NULL);
return JNI_FALSE;
}
// 将Java层的Parcel对象转化成为Native层的Parcel对象。
Parcel* data = parcelForJavaObject(env, dataObj);
if (data == NULL) {
return JNI_FALSE;
}
// 将Java层的Parcel对象转化成为Native层的Parcel对象。
Parcel* reply = parcelForJavaObject(env, replyObj);
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
// 已知BpBinder会保存到BinderProxy的成员变量mObject中,因此在这里会从BinderProxy的成员变量mObject中获取BpBinder。
IBinder* target = getBPNativeData(env, obj)->mObject.get();
if (target == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
return JNI_FALSE;
}
...
// 调用BpBinder的transact函数,向Binder驱动发送数据,可以看出Java Binder是需要Native Binder支持的,最终的目的就是向Binder驱动发送和接收数据。
status_t err = target->transact(code, *data, reply, flags);
return JNI_FALSE;
}

引出JavaBBinder

接着回过头来分析data.writeStrongBinder(service),代码如下所示。Parcel.java

1
2
3
public final void writeStrongBinder(IBinder ll) {
nativeWriteStrongBinder(mNativePtr, val);
}

nativeWriteStrongBinder是Native方法,实现的函数为android_os_Parcel_writeStrongBinder:android_os_Parcel.cpp

1
2
3
4
5
6
7
8
9
10
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}

接着查看 ibinderForJavaObject 函数:android_util_Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
// 如果obj是Java层的Binder类,那么先获取JavaBBinderHolder对象,然后调用JavaBBinderHolder的get函数.
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh->get(env, obj);
}
// 如果obj是Java层的BinderProxy类,则返回BpBinder。
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return getBPNativeData(env, obj)->mObject;
}

ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class JavaBBinderHolder
{
public:
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
// 成员变量mBinder是`wp<JavaBBinder>`类型的弱引用
// 得到`sp<JavaBBinder>`类型的强引用b
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
// obj是一个Java层Binder对象
// 创建JavaBBinder并赋值给b
b = new JavaBBinder(env, obj);
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
// JavaBBinderHolder的get函数返回的是JavaBBinder。
return b;
}
sp<JavaBBinder> getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp<JavaBBinder> mBinder;
};

data.writeStrongBinder(service)在本文中等价于:

1
data.writeStrongBinder(new JavaBBinder(env,Binder))。

讲到这里可以得知ServiceManager.addService()传入的并不是AMS本身,而是JavaBBinder。

解析JavaBBinder

接着来分析JavaBBinder,查看它的构造函数:android_util_Binder.cpp::JavaBBinderHolder::JavaBBinder

1
2
3
4
5
6
7
8
9
10
11
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject /* Java Binder */ c)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
gcIfManyNewRefs(env);
}
...

可以发现JavaBBinder继承了BBinder,那么JavaBBinder的作用是什么呢?当Binder驱动得到客户端的请求,紧接着会将响应发送给JavaBBinder,这时会调用JavaBBinder的onTransact函数,代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
// 调用了Java层Binder的execTransact函数
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

...
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}

查看 execTransact 函数。Binder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
...
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
// AMS实现了onTransact函数,从而完成业务实现。从这里可有看出,JavaBBinder并没有实现什么业务,当它接收到请求时,会调用Binder类的execTransact函数,execTransact函数内部又调用了onTransact函数,系统服务会重写onTransact函数来实现自身的业务功能。
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
...
}
...
return res;
}

Java Binder架构

Native Binder的部分在此前的文章已经讲过,这里主要来说说Java Binder部分,从图中可以看到:
1.Binder是服务端的代表,JavaBBinder继承BBinder,JavaBBinder通过mObject变量指向Binder。
2.BinderProxy是客户端的代表,ServiceManager的addService等方法会交由ServiceManagerProxy处理。
3.ServiceManagerProxy的成员变量mRemote指向BinderProxy对象,所以ServiceManagerProxy的addService等方法会交由BinderProxy来处理。
4.BinderProxy的成员变量mObject指向BpBinder对象,因此BinderProxy可以通过BpBinder和Binder驱动发送数据。


备注

注:源码基于 Android 9.0 版本

参考资料:
Android 开发艺术探索

http://liuwangshu.cn/tags/Binder%E5%8E%9F%E7%90%86/

http://gityuan.com/tags/#binder

https://xiaozhuanlan.com/topic/9405168327

https://www.jianshu.com/p/adaa1a39a274