本文涉及到的源码路径:
frameworks/av/media/mediaserver/main_mediaserver.cpp
frameworks/native/libs/binder/ProcessState.cpp
frameworks/native/libs/binder/IServiceManager.cpp
frameworks/native/libs/binder/include/binder/IInterface.h
frameworks/native/libs/binder/Binder.cpp
frameworks/native/libs/binder/include/binder/IBinder.h
frameworks/native/libs/binder/include/binder/BpBinder.h
frameworks/native/libs/binder/include/binder/Binder.h
bionic/libc/kernel/uapi/linux/android/binder.h
frameworks/native/cmds/servicemanager/service_manager.c
frameworks/native/cmds/servicemanager/binder.c
frameworks/av/media/libmedia/IMediaDeathNotifier.cpp
frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
frameworks/av/media/libmedia/mediaplayer.cpp
binder 概述
binder 是 Android 系统提供的一种 IPC 机制,Android 系统基本上可以看做是一个基 于 binder 的 C/S 架构,binder 像网络一样把系统的各个部分紧密地连接在一起
从 mediaserver 看 binder
mediaserver 是一个由 c++ 实现的可执行程序,包括:
- AudioFlinger:音频中的核心服务
- AudioPolicyService:音频系统中关于音频策略的重要服务
- MediaPlayerService:多媒体系统中的重要服务
- CameraService:有关相机的重要服务
mediaserver main 函数源码
1
2
3
4
5
6
7
8
9
10
11
12
int main(int argc __unused, char **argv __unused) {
// 1、获取一个 ProcessState 实例
sp<ProcessState> proc(ProcessState::self());
// 2、获取 ServiceMananger 实例
sp<IServiceManager> sm(defaultServiceManager());
// 3、初始化 MediaPlayer 服务
MediaPlayerService::instantiate();
// 4、创建
ProcessState::self()->startThreadPool();
// 5、加入
IPCThreadState::self()->joinThreadPool();
}
ProcessState (1)
1、ProcessState::self()
1
2
3
4
5
6
7
8
9
10
sp<ProcessState> ProcessState::self() {
// 单例模式,即每个进程只有一个该对象
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
// 创建 ProcessState 对象,在构造器中打开 binder
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
2、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
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
// 悄咪咪地打开 /dev/binder 设备,Android 内核为 IPC 专门设置的一个虚拟设备
, 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(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1) {
if (mDriverFD >= 0) {
// BINDER_VM_SIZE 定义为 1*2014*1024 - 4096*2 = 1M - 8k
// 执行完 mmap 之后,binder 驱动会分配一块内存来接收数据
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE
| MAP_NORESERVE, mDriverFD, 0);
// ...
}
}
3、打开 binder 设备
1
2
3
4
5
6
7
8
9
10
11
12
13
14
static int open_driver(const char *driver) {
// 打开 /dev/binder 设备
int fd = open(driver, O_RDWR | O_CLOEXEC);
if (fd >= 0) {
// 通过 ioctl 校验版本号
int vers = 0;
status_t result = ioctl(fd, BINDER_VERSION, &vers);
// ...
// 通过 ioctl 告诉 binder 驱动,fd 最多支持 15 个线程
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS/*15*/;
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
}
return fd;
}
总结一下 ProcessState::self() 所做的事:
- 打开
/dev/binder
设备,及打开与内核的 binder 驱动的通道; - 对打开的文件句柄使用
mmap
,让 binder 驱动分配一块内存来接收数据; - 由于 ProcessState 是单例,因此每个进程只会打开设备一次
defaultServiceManager() 函数 (2)
1、IServiceManager.cpp::defaultServiceManager()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sp<IServiceManager> defaultServiceManager() {
// 单例模式,若已初始化则直接返回
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
// 自动锁,在程序返回时会自动释放
AutoMutex _l(gDefaultServiceManagerLock);
// 若对象未创建,则等待直到创建完成
while (gDefaultServiceManager == NULL) {
// interface_cast 这个宏是什么作用呢?见 4.2
gDefaultServiceManager = interface_cast<IServiceManager>(
// 此处传入的 NULL 参数非常关键,下面来分析一下
ProcessState::self()->getContextObject(NULL));
// 睡一会儿,休息休息
if (gDefaultServiceManager == NULL) sleep(1);
}
}
return gDefaultServiceManager;
}
2、ProcessState::self()->getContextObject(NULL)
1
2
3
4
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) {
// 函数返回值是 IBinder
return getStrongProxyForHandle(0/*NULL*/);
}
3、ProcessState::self()->getStrongProxyForHandle()
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
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) {
sp<IBinder> result;
AutoMutex _l(mLock);
// 根据索引查询对应的句柄,若未找到则创建一个新的并返回
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// 初始状态下,e->binder 是 NULL
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
// 此时传入的 handle 为 0,对应的就是 ServiceManager
if (handle == 0) {
// ping 下,看看是不是挂掉了
Parcel data;
// IPCThreadState 稍后再分析
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT) return NULL;
}
// 创建 BpBinder(静态工厂),即 new BpBinder(handle)
// 接下来分析 BpBinder 与 BBinder
b = BpBinder::create(handle);
// 填充内容
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
}
}
return result; // new BpBinder(0)
}
4、BpBinder 与 BBinder 是什么?
BpBinder 与 BBinder 都是 Android 中与 Binder 通信相关的代表,他们都由 IBinder 派生,如下是他们的族谱:
- BpBinder 是客户端用来与 Server 交互的代理类(p 可理解为 proxy);
- BBinder 则是与 proxy 相对的一端,即 pxory 交互的目标(服务端代理)
- BpBinder 与 BBinder 一一对应,即 BpBinderA 只能与 BBinderA 对应
① 为什么在 defaultServiceManager()
中创建了 BpBinder 而不是 BBinder?
- 目前,我们还是 ServiceManager 的客户端,所以用 BpBinder 来进行交互
② BpBinder 如何与 BBinder 一一对应?
- 还记得上述代码中的
handle
么,binder 系统是用handle
来进行标识的
③ handle = 0
时,表示什么?
- 0 在 binder 系统中有重要的含义,即 0 代表的就是 ServiceManager 所对应的 BBinder。可以理解为 0 号服务就是 ServiceManager,0 号服务管理其他服务
4.1、BpBinder
构造
1
2
3
4
5
6
7
8
9
10
11
12
BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
, mTrackedUid(trackedUid) {
// 怎么感觉这里什么也没做呢?回想代码是从 defaultServiceManager() 中开始
// 的,回头看下我们是不是有什么细节遗漏了?哦!原来是 interface_cast 这个宏
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle, this);
// 最终返回到 defaultServiceManager() 中
}
5、被遗忘的宏 interface_cast
从 IInterface.h
中来
1
2
3
4
5
6
7
8
9
10
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) {
return INTERFACE::asInterface(obj);
}
// 对 defaultServiceManager() 中的 interface_cast<IServiceManager>(obj) 展开如下:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj) {
// 兜兜转转现在又回到 IServiceManager 中了
return IServiceManager::asInterface(obj);
}
6、千呼万唤始出来 IServiceManager.cpp::asInterface
- IServiceManager 定义了 ServiceManager 所需的一系列业务接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class IServiceManager : public IInterface {
public:
// 重要的宏,稍后分析
DECLARE_META_INTERFACE(ServiceManager)
/* 以下是 ServiceManager 中所需的一系列业务接口 */
// 从 ServiceManager 中查询服务
virtual sp<IBinder> getService( const String16& name) const = 0;
virtual sp<IBinder> checkService( const String16& name) const = 0;
// 向 ServiceManager 添加/注册一个服务
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;
}
// 重要的宏,稍后分析
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
- 通过宏
DECLARE_META_INTERFACE
和宏IMPLEMENT_META_INTERFACE
将业务与通信结合
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
// 宏定义:声明
#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(); \
// 宏定义:实现
#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() { } \
- 将以上两个宏代入 ServiceManager 后展开如下:
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
/////////////////////// 声明一些函数和变量
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();
/////////////////////// 实现上述声明的函数和变量
const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager")
const ::android::String16& IServiceManager::getInterfaceDescriptor() const {
// 即 android.os.IServiceManager
return IServiceManager::descriptor
}
::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(IServiceManager 的内嵌类)
// 这里的 obj 是在 #3 中创建的 BpBinder(0)
intr = new BpServiceManager(obj);
}
}
return intr;
}
// 实现构造函数和析构函数
IServiceManager::IServiceManager() {}
IServiceManager::~IServiceManager() {}
7、IServiceManager 家族族谱如下:
可知:
- IServiceManager、BpServiceManager 和 BnServiceManager 都与业务逻辑相关
- BnServiceManager 同时从 IServiceManager BBinder 派生,表示它可直接参与 Binder 通信
- BpServiceManager 虽然从 BpInterface 中派生,但是这条分支似乎与 BpBinder 没有关系
- BnServiceManager 是一个虚类,它的业务函数最终需要子类来实现
7.1、IServiceManager.cpp::BpServiceManager
类
1
2
3
4
5
6
7
8
class BpServiceManager : public BpInterface<IServiceManager> {
public:
explicit BpServiceManager(const sp<IBinder>& impl)
// 这里调用父类构造,impl 是 IBinder 类型与 Binder 相关,实际是 BpBinder 对象
: BpInterface<IServiceManager>(impl) { }
// 省略具体的业务函数:
// checkService(), addService(), getService(), listService()
}
7.2、IInterface.h::BpInterface
类
1
2
3
4
5
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
// 继续调用父类构造,其具体实现在 Binder.cpp 中
: BpRefBase(remote) {
}
7.3、Binder.cpp::BpRefBase
类
1
2
3
4
5
6
7
8
9
10
BpRefBase::BpRefBase(const sp<IBinder>& o)
// 此处的 mRemote 即上面创建的 BpBinder(0)
: mRemote(o.get()), mRefs(NULL), mState(0) {
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); // Removed on first IncStrong().
mRefs = mRemote->createWeak(this); // Held for our entire lifetime.
}
// 最终:BpServiceManager::mRemote 指向 BpBinder()
}
8、总结一下 defaultServiceManager()
函数
- 创建 BpBinder 对象,其 handle 值为 0
- 创建 BpServiceManager 对象,其 mRemote 指向 BpBinder(0)
- BpServiceManager 内部实现了 IServiceManager 中定义的业务接口
注册 MediaPlayerService (3)
1、MediaPlayService.cpp::instantiate()
1
2
3
4
5
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
// 即 BpServiceManager::addService()
}
1.1、中转站一 IServiceManager.cpp::BpServiceManager::addService()
函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority) {
// data 是要打包发送的数据,reply 是要接收的数据
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
data.writeInt32(dumpsysPriority);
// 打包发送并接收数据
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
// remote() 方法返回 mRemote 即 BpBinder 对象
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
1.2、中转站二 BpBinder.cpp::transact()
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) {
// 把实际的苦活交给 IPCThreadState 来干,下面着重分析
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
2、真正脚踏实地干活的 IPCThreadState
类
2.1、线程中单例 IPCThreadState::self()
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
IPCThreadState* IPCThreadState::self() {
// 每个线程只会有一个实例
if (gHaveTLS) {
restart:
// 如果已经 set,则根据 key 获取相关内容
const pthread_key_t k = gTLS;
// TLS 全称为 Thread Local Storage,线程本地存储,顾名思义这是线程内部
// 的私有空间,并不会与其他线程共享
// linux 内核提供了 pthread_set/getspecific() 函数来设置/获取线程私有
// 空间的内容所以有 get 的地方肯定有 set
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
// 构造函数中会调用 set 方法
return new IPCThreadState;
}
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {
// 如果没有设置过,则先创建 key 再进行设置
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
if (key_create_value != 0) {
// 创建 key 失败,释放锁并返回 NULL
pthread_mutex_unlock(&gTLSMutex);
return NULL;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
// 跳转到 set 的地方去,这个地方用的妙啊!
goto restart;
}
2.2、IPCThreadState
构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0) {
// 有 get 必有 set,Android 诚不我欺
pthread_setspecific(gTLS, this);
clearCaller();
// mIn 和 mOut 是两个 Parcel 类型的对象
// mIn 可以看做接收来自 Binder 数据的缓冲区
// mOut 可以看做发送数据到 Binder 的缓冲区
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
2.3、马不停蹄的 transact()
函数
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
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;
// BR_ 开头的是回复消息,定义在 binder_driver_return_protocol 枚举中
// BC_ 开头的是发送消息,定义在 binder_driver_command_protocol 枚举中
// 向 binder 发送数据
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
// TF_ONE_WAY 这个是什么东东?
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
// 接收 binder 返回的数据
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
2.3.1、发送数据 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
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_transaction_data 结构体中
tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
// handle 值传递给 target,用来标识 target 端,0 表示 ServiceManager
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
// 检查数据是否合法
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) {
// TF_STATUS_CODE 又是什么东东
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);
}
// 将数据填充到缓冲区等待发送,那实际发送数据是在哪里呢?
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
2.3.2、接收数据 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
status_t IPCThreadState::waitForResponse(Parcel *reply,
status_t *acquireResult) {
uint32_t cmd;
int32_t err;
// 等待直到返回或者错误
while (1) {
// 重要的 talkViewDriver() 函数,直接与 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();
switch (cmd) {
// ...
default:
// 执行命令
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
if (err != NO_ERROR) {
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
2.3.3、executeCommand()
函数
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
status_t IPCThreadState::executeCommand(int32_t cmd) {
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
case BR_OK:
break;
// ...
// 重点看这个,其他的先略过
case BR_TRANSACTION: {
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
if (result != NO_ERROR) break;
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
Parcel reply;
status_t error;
if (tr.target.ptr) {
// 将 tr.target.ptr 强转为 RefBase::weakref_type 指针后调用
// attemptIncStrong() 方法,获取一个强引用
if (reinterpret_cast<RefBase::weakref_type*>(
tr.target.ptr)->attemptIncStrong(this)) {
// 将 tr.cookie 强转为 BBinder 指针后调用 transact() 方法
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(
tr.code, buffer, &reply, tr.flags);
// 将 tr.cookie 强转为 BBinder 指针后调用 decStrong() 方法
// 减少一次强引用计数
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
} else error = UNKNOWN_TRANSACTION;
} else {
// the_context_object 是 IPCThreadState 中定义的一个全局变量:
// sp<BBinder> the_context_object;,可通过 setTheContextObject() 来设置
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
// 又又又又遇到了 TF_ONE_WAY
if ((tr.flags & TF_ONE_WAY) == 0) {
if (error < NO_ERROR) reply.setError(error);
sendReply(reply, 0);
}
mCallingPid = origPid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
} break;
// ...
case BR_DEAD_BINDER: {
// 收到驱动的指示:service 挂掉了,BpBinder 要做一些事儿了
BpBinder *proxy = (BpBinder*)mIn.readPointer();
// BpBinder 做的事儿在这,有趣的地方,稍后再看
proxy->sendObituary();
mOut.writeInt32(BC_DEAD_BINDER_DONE);
mOut.writePointer((uintptr_t)proxy);
} break;
case BR_SPAWN_LOOPER:
// 收到驱动的指示:要创建一个新的线程用来与 binder 通信
mProcess->spawnPooledThread(false);
break;
// ...
}
return result;
}
2.4、与 binder 交互 talkWithDriver()
函数
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
status_t IPCThreadState::talkWithDriver(bool doReceive) {
if (mProcess->mDriverFD <= 0) {
return -EBADF;
}
binder_write_read bwr;
// Is the read buffer empty?
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
// We don't want to write anything if we are still reading
// from data left in the input buffer and the caller
// has requested to read the next data.
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
// 结构体填充
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
// This is what we'll read.
if (doReceive && needRead) {
// 接收数据缓冲区填充,如果接收到数据就直接填充在 mIn 中
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
// Return immediately if there is nothing to do.
if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
bwr.write_consumed = 0;
bwr.read_consumed = 0;
status_t err;
do {
// 通过 ioctl 与 binder 设备进行交互,暂时先到这里
// 再向下深入的话需要去分析驱动层的源码了
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
if (mProcess->mDriverFD <= 0) {
err = -EBADF;
}
} while (err == -EINTR);
if (err >= NO_ERROR) {
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else {
mOut.setDataSize(0);
processPostWriteDerefs();
}
}
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
return NO_ERROR;
}
return err;
}
startThreadPool() 和 joinThreadPool() (4/5)
1、ProcessState.cpp::startThreadPool()
函数
1
2
3
4
5
6
7
8
void ProcessState::startThreadPool() {
AutoMutex _l(mLock);
// 如果未执行过才会执行以下分支
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
1.1、ProcessState.cpp::spawnPooledThread()
函数
1
2
3
4
5
6
7
8
9
10
void ProcessState::spawnPooledThread(bool isMain) {
// 此处的 isMain 为 true
if (mThreadPoolStarted) {
// 生成线程名,其格式为:"Binder:%d_%X", pid, seq
String8 name = makeBinderThreadName();
// 创建 PoolThread 并执行
sp<Thread> t = new PoolThread(isMain/*true*/);
t->run(name.string());
}
}
1.2、ProcessState 的内嵌类 PoolThread:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PoolThread : public Thread {
public:
explicit PoolThread(bool isMain)
// 调用父类,将值传递给 mIsMain(true)
: mIsMain(isMain) { }
protected:
virtual bool threadLoop() {
// mIsMain 为 true,最终调用到 IPCThreadState
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
}
2、IPCThreadState.cpp::joinThreadPool()
函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void IPCThreadState::joinThreadPool(bool isMain) {
// isMain 为 true, 此处写入 BC_ENTER_LOOPER 指令,进入循环
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
// 处理已经 dead 的 BBinder 对象
processPendingDerefs();
// 不停地获取并执行下一条指令
result = getAndExecuteCommand();
// ...
} while (result != -ECONNREFUSED && result != -EBADF);
// 退出循环
mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(false);
}
2.1、IPCThreadState.cpp::getAndExecuteCommand()
函数
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
status_t IPCThreadState::getAndExecuteCommand() {
status_t result;
int32_t cmd;
// 发送指令,读取请求
result = talkWithDriver();
if (result >= NO_ERROR) {
size_t IN = mIn.dataAvail();
if (IN < sizeof(int32_t)) return result;
// 读取一条指令
cmd = mIn.readInt32();
pthread_mutex_lock(&mProcess->mThreadCountLock);
mProcess->mExecutingThreadsCount++;
if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
mProcess->mStarvationStartTimeMs == 0) {
mProcess->mStarvationStartTimeMs = uptimeMillis();
}
pthread_mutex_unlock(&mProcess->mThreadCountLock);
// 执行命令,构成了循环调用
result = executeCommand(cmd);
pthread_mutex_lock(&mProcess->mThreadCountLock);
mProcess->mExecutingThreadsCount--;
if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&
mProcess->mStarvationStartTimeMs != 0) {
mProcess->mStarvationStartTimeMs = 0;
}
pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
pthread_mutex_unlock(&mProcess->mThreadCountLock);
}
return result;
}
总结:
- 1、从以上来看,有几个 Thread 在为 Service 服务呢?
- startThreadPool 中启动的线程通过 joinThreadPool 读取 binder 设备,查看是否有请求
- main 线程也调用 joinThreadPool 读取 binder 设备,查看是否有请求
- 2、由此可见,binder 设备是支持多线程操作的
- 3、Binder 通信和基于 Binder 通信的业务之间的关系:
- Binder 是通信机制
- 业务可以基于 Binder 通信,当然也可以使用其他的 IPC 手段
- 4、binder 通信和业务层的关系图如下:
服务大总管 service manager
前面提到 defaultServiceMannager() 返回一个 BpServiceManager 对象,通过它可以把 请求发送给 handle 值为 0 的目的端,即 BnServiceManager 来处理请求,但是源码中 并没有这样一个类;然而系统提供了一个 service_manager.c 程序,它完成的就是 BnServiceManager 的工作。
ServiceManager 原理
1、service_manager.c::main()
函数
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
int main(int argc, char** argv) {
struct binder_state *bs;
union selinux_callback cb;
char *driver;
if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}
// ①打开 binder 设备,mmap 大小为 128k
bs = binder_open(driver, 128*1024);
if (!bs) {
// 打开失败,打印 log 并返回
return -1;
}
// ②让自己成为大管家,是不是把自己的 handle 设置为 0 呢?
if (binder_become_context_manager(bs)) {
return -1;
}
// selinux 配置项
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
sehandle = selinux_android_service_context_handle();
selinux_status_open(true);
if (sehandle == NULL) {
abort();
}
if (getcon(&service_manager_context) != 0) {
abort();
}
// ③开始干活儿,处理客户端发过来的请求
// 参数 func 是一个函数指针,指向 svcmgr_handler 函数,用于解析客户端请求
binder_loop(bs, svcmgr_handler/*binder_handler func*/);
return 0;
}
2、打开 binder 设备:service_manager.c::open_binder()
1
2
3
4
5
6
7
8
9
10
11
12
struct binder_state *binder_open(const char* driver, size_t mapsize) {
struct binder_state *bs;
//...
// 打开设备,返回文件句柄
bs->fd = open(driver, O_RDWR | O_CLOEXEC);
// ...
// 内存映射
bs->mapsize = mapsize;
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
// ...
return bs;
}
3、成为老大:service_manager.c::binder_become_context_manager()
1
2
3
4
int binder_become_context_manager(struct binder_state *bs) {
// 此处传递的参数是 0,指令是 BINDER_SET_CONTEXT_MGR
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
4、开始干活儿:service_manager.c::binder_loop()
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
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(bs, readbuf, sizeof(uint32_t));
// 开始无限循环
for (;;) {
// 继续填充参数
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
// 向 binder 驱动要个事情来做
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
break;
}
// 接收并解析请求,最终将调用 svcmgr_handler 函数
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
// ...
}
}
4.1、解析请求:service_manager.c::binder_parse()
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
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);
switch(cmd) {
// ...
case BR_TRANSACTION: {
struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
// ...
// 如果处理函数不为空
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);
// 处理请求
res = func(bs, txn, &msg, &reply);
// ...
}
break;
}
// ...
}
}
return r;
}
5、处理请求:service_manager.c::svcmgr_handler()
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply) {
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
uint32_t dumpsys_priority;
// BINDER_SERVICE_MANAGER 魔数,定义为 0
if (txn->target.ptr != BINDER_SERVICE_MANAGER)
return -1;
if (txn->code == PING_TRANSACTION)
return 0;
// Equivalent to Parcel::enforceInterface(), reading the RPC
// header with the strict mode policy mask and the interface name.
// Note that we ignore the strict_policy and don't propagate it
// further (since we do no outbound RPCs anyway).
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
if ((len != (sizeof(svcmgr_id) / 2)) ||
memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
fprintf(stderr,"invalid id %s\n", str8(s, len));
return -1;
}
if (sehandle && selinux_status_updated() > 0) {
struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
if (tmp_sehandle) {
selabel_close(sehandle);
sehandle = tmp_sehandle;
}
}
switch(txn->code) {
case SVC_MGR_GET_SERVICE: // getService()
case SVC_MGR_CHECK_SERVICE: // checkService()
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;
case SVC_MGR_ADD_SERVICE: // addService()
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
dumpsys_priority = bio_get_uint32(msg);
if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated,
dumpsys_priority, txn->sender_pid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: { // listService()
uint32_t n = bio_get_uint32(msg);
uint32_t req_dumpsys_priority = bio_get_uint32(msg);
if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
return -1;
}
si = svclist;
// walk through the list of services n times skipping services that
// do not support the requested priority
while (si) {
if (si->dumpsys_priority & req_dumpsys_priority) {
if (n == 0) break;
n--;
}
si = si->next;
}
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
return -1;
}
bio_put_uint32(reply, 0);
// 以上,实现了所有在 IServiceManager 中定义的业务函数
return 0;
}
总结:
1、svcmgr_handler
函数实现了所有在 IServiceManager 中定义的业务函数
service 注册
1、service_manager.c::do_add_service()
函数
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 do_add_service(struct binder_state *bs, const uint16_t *s, size_t len,
uint32_t handle,uid_t uid, int allow_isolated, uint32_t dumpsys_priority,
pid_t spid) {
struct svcinfo *si;
if (!handle || (len == 0) || (len > 127))
return -1;
// ①检查服务是否可以注册
if (!svc_can_register(s, len, spid, uid)) {
return -1;
}
// ②检查服务是否已存在,根据服务名的长度和名字是否相同来判断
si = find_svc(s, len);
if (si) {
if (si->handle) {
// 通知 service 已挂
svcinfo_death(bs, si);
}
// 服务已存在,更新一下
si->handle = handle;
} else {
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
if (!si) {
return -1;
}
// ③保存服务
si->handle = handle;
si->len = len;
memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
si->name[len] = '\0';
// service 退出的通知函数 svcinfo_death
si->death.func = (void*) svcinfo_death;
si->death.ptr = si;
si->allow_isolated = allow_isolated;
si->dumpsys_priority = dumpsys_priority;
// 当前 service 的 next 指针指向表头
si->next = svclist;
// 保存 service 到表头
svclist = si;
}
binder_acquire(bs, handle);
binder_link_to_death(bs, handle, &si->death);
return 0;
}
2、检查服务是否可以注册: service_manager.c::svc_can_register()
1
2
3
4
5
6
7
8
9
10
11
12
13
static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid,
uid_t uid) {
const char *perm = "add";
// 不允许 app 注册服务
if (multiuser_get_app_id(uid) >= AID_APP) {
return 0;
}
// 检查是否有某项权限(add/find)
// 高版本是通过 selinux 来检查的
// 低版本通过定义一个 allowed 数组来判断,如果没有达到 root 和 system 权
// 限是无法添加的
return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
}
ServiceManager 存在的意义
- 1、ServiceManager 能集中管理系统中的所有服务,能够施加权限控制,并不是所有 的进程都可注册服务;
- 2、ServiceManager 支持通过字符串名称来查找对应的 service,有点像 DNS;
- 3、server 进程可能会挂掉,如果让每个 client 自己来检测的话压力会很大,现在 只需向 ServiceManager查询一下就能够轻松知道
service 以及它的 client
以 MediaPlayerService 和 它的 client 为例
client 查询 service
一个 client 若想使用某个 service,就必须通过调用 ServiceManager::getService() 函数来查询该 service。比如:IMediaDeathNotifier.cpp::getMediaPlayerService()
1、查询服务 IMediaDeathNotifier.cpp::getMediaPlayerService()
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
const sp<IMediaPlayerService> IMediaDeathNotifier::getMediaPlayerService() {
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
// 查询 media.player service, 如果还没注册上则每隔 0.5s 查询一次,直到
// 注册成功
do {
// 想要与 service 通信,必须拿到一个 BpBinder 对象
binder = sm->getService(String16("media.player"));
if (binder != 0) {
break;
}
usleep(500000); // 0.5 s
} while (true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
// 注册服务死亡通知,用于服务挂掉时接收通知
binder->linkToDeath(sDeathNotifier);
// 调用 asInterface() 方法拿到 BpMediaPlayerService 对象之后,就能够使
// 用其中的业务函数了,比如:createMetadataRetriever()、
// createMediaRecorder() 等,当然也仅仅是交给其打包转发而已,具体的实
// 现在 BnMediaPlayerService
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
return sMediaPlayerService;
}
2、转发业务码:BnMediaPlayerService::onTransact()
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
66
67
status_t BnMediaPlayerService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IMediaPlayerClient> client =
interface_cast<IMediaPlayerClient>(data.readStrongBinder());
audio_session_t audioSessionId = (audio_session_t) data.readInt32();
// 子类要实现 create() 虚函数
sp<IMediaPlayer> player = create(client, audioSessionId);
reply->writeStrongBinder(IInterface::asBinder(player));
return NO_ERROR;
} break;
case CREATE_MEDIA_RECORDER: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const String16 opPackageName = data.readString16();
// 子类要实现 createMediaRecorder() 虚函数
sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName);
reply->writeStrongBinder(IInterface::asBinder(recorder));
return NO_ERROR;
} break;
case CREATE_METADATA_RETRIEVER: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
// 子类要实现 createMetadataRetriever() 虚函数
sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
reply->writeStrongBinder(IInterface::asBinder(retriever));
return NO_ERROR;
} break;
case ADD_BATTERY_DATA: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
uint32_t params = data.readInt32();
// 子类要实现 addBatteryData() 虚函数
addBatteryData(params);
return NO_ERROR;
} break;
case PULL_BATTERY_DATA: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
// 子类要实现 pullBatteryData() 虚函数
pullBatteryData(reply);
return NO_ERROR;
} break;
case LISTEN_FOR_REMOTE_DISPLAY: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const String16 opPackageName = data.readString16();
sp<IRemoteDisplayClient> client(
interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
if (client == NULL) {
reply->writeStrongBinder(NULL);
return NO_ERROR;
}
String8 iface(data.readString8());
// 子类要实现 listenForRemoteDisplay() 虚函数
sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));
reply->writeStrongBinder(IInterface::asBinder(display));
return NO_ERROR;
} break;
case GET_CODEC_LIST: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
// 子类要实现 getCodecList() 虚函数
sp<IMediaCodecList> mcl = getCodecList();
reply->writeStrongBinder(IInterface::asBinder(mcl));
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
service 工作
具体的业务逻辑是由 MediaPlayerService.cpp 来实现的,以 create() 为例来看一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
audio_session_t audioSessionId) {
pid_t pid = IPCThreadState::self()->getCallingPid();
int32_t connId = android_atomic_inc(&mNextConnId);
// 创建 Client 对象
sp<Client> c = new Client(this, pid, connId, client, audioSessionId,
IPCThreadState::self()->getCallingUid());
wp<Client> w = c;
{
Mutex::Autolock lock(mLock);
// 记录 client
mClients.add(w);
}
// 返回 client 引用
return c;
}
总结:
- BpXxxService:client 端访问 service 时,service 端派出的代理;
- BnXxxService:service 端负责转发 service 代理发送的请求;
- XxxService:service 端真正实现业务逻辑的地方;
拓展思考
binder 驱动的实现:
- 驱动代码是在 kernel/drivers/staing/android/binder.c 中(Android 4.4),该目录 下还有一个 binder.h 头文件
- /proc/binder 目录下的内容可用来查看 binder 设备的运行情况
binder 与线程的关系
以 MediaService 为例,如果程序正常运行,则:
- 通过 startThreadPool() 启动一个线程,这个线程在 talkWithDriver();
- 主线程通过 joinThreadPool() 也在 talkWithDriver();
- binder 设备把发起请求的线程牢牢地拴住,必须收到回复才会放它离开;
关于 DeathRecipient
字面意思翻译是‘死亡接收者’,也就是说,如果想要收到服务死亡的通知就必须要设 置一个 DeathRecipient
1、设置 DeathRecipient
1
2
3
4
5
6
7
8
9
10
11
12
const sp<IMediaPlayerService> IMediaDeathNotifier::getMediaPlayerService() {
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
// 伪代码
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
// 注册服务死亡通知,用于服务挂掉时接收通知
binder->linkToDeath(sDeathNotifier);
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
return sMediaPlayerService;
}
2、发送 service dead 通知
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
status_t IPCThreadState::executeCommand(int32_t cmd) {
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
// ...
case BR_DEAD_BINDER: {
// 收到驱动的指示:service 挂掉了,BpBinder 要做一些事儿了
// 至于驱动是如何实现的,则要去分析驱动源码,在此略过
BpBinder *proxy = (BpBinder*)mIn.readPointer();
// 通知 service 挂掉了
proxy->sendObituary();
mOut.writeInt32(BC_DEAD_BINDER_DONE);
mOut.writePointer((uintptr_t)proxy);
} break;
// ...
}
return result;
}
2.1、BpBinder.cpp::sendObituary()
1
2
3
4
5
6
7
8
9
10
11
void BpBinder::sendObituary() {
// ...
if (obits != NULL) {
const size_t N = obits->size();
for (size_t i=0; i<N; i++) {
// 逐个发送报告
reportOneDeath(obits->itemAt(i));
}
delete obits;
}
}
2.2、BpBinder.cpp::reportOneDeath()
1
2
3
4
5
6
void BpBinder::reportOneDeath(const Obituary& obit) {
sp<DeathRecipient> recipient = obit.recipient.promote();
if (recipient == NULL) return;
// 回调 DeathRecipient 对象的 binderDied() 方法
recipient->binderDied(this);
}
3、如何接收到 service dead 通知
1
2
3
4
5
6
7
8
9
10
void IMediaDeathNotifier::DeathNotifier::binderDied(const wp<IBinder>& who __unused) {
// ...
for (size_t iter = 0; iter < list.size(); ++iter) {
sp<IMediaDeathNotifier> notifier = list[iter].promote();
if (notifier != 0) {
// 以 MediaPlayer 为例分析
notifier->died();
}
}
}
4、接下来看 MediaPlayer 内部如何处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void MediaPlayer::died() {
ALOGV("died");
// 通用方法,其他的消息比如 MEDIA_PREPARED 等也会从 notify() 发出去
notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
}
void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj) {
ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
switch (msg) {
// ...
case MEDIA_ERROR:
ALOGE("error (%d, %d)", ext1, ext2);
// 处理异常
break;
// ...
}
// ...
}
匿名 service
所谓匿名 service 就是没有注册到 ServiceManager 中的 Service;但既然是一个 Service,那就表明它确实是一个基于 Binder 通信的 C/S 结构。还是以 MediaPlayerService 分析。
1、IMediaPlayerService.cpp::onTransact()
CREATE 命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
status_t BnMediaPlayerService::onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags) {
switch (code) {
case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IMediaPlayerClient> client =
interface_cast<IMediaPlayerClient>(data.readStrongBinder());
audio_session_t audioSessionId = (audio_session_t) data.readInt32();
// 子类实现 create() 虚函数创建一个 IMediaPlayer 对象
// 此后 client 就可以直接使用 IMediaPlayer 来跨进程执行函数调用
sp<IMediaPlayer> player = create(client, audioSessionId);
// 将 binder 作为一种特殊的数据类型来处理
reply->writeStrongBinder(IInterface::asBinder(player));
return NO_ERROR;
} break;
// ...
}
}
以上代码所展示的 C/S 结构:
- BpMediaPlayer:由 MediaPlayerClient 使用,调用 IMediaPlayer 提供的业务接口;
- BnMediaPlayer:由 MediaPlayerService 使用,处理来自 client 端的业务请求;
另外要注意一下 reply->writeStrongBinder(IInterface::asBinder(player))
这句, 当 reply 写到 binder 驱动时,驱动可能会特殊处理这种 IBinder 类型的数据,比如 为这个 BBinder 计算生成一个唯一的 handle 值,其实这就相当于在 binder 驱动中注 册了一项服务。通过这种方式,MediaServer 输出了大量的服务,比如 IMediaPlayer、 IMediaRecorder 等
实践:如何实现一个 native service
总结
除了 binder 之外,Android 中的其他 IPC 手段
1、pipe、socket、文件共享、共享内存
binder 相较于其他 IPC 手段的优点
1、一次 copy; 2、有校验,安全;
从一个 anr 实例看 binder 整体调用流程
native: #02 pc 000000000005a844 /system/lib64/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+260)
native: #03 pc 000000000005b718 /system/lib64/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+360)
native: #04 pc 000000000005b438 /system/lib64/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+176)
native: #05 pc 00000000000513e8 /system/lib64/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+72)
native: #06 pc 0000000000131558 /system/lib64/libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)+152)
at android.os.BinderProxy.transactNative(Native method)
at android.os.BinderProxy.transact(Binder.java:1127)
at com.android.internal.app.IBatteryStats$Stub$Proxy.getStatisticsStream(IBatteryStats.java:1364)
at com.android.internal.os.BatteryStatsHelper.getStats(BatteryStatsHelper.java:1032)
at com.android.internal.os.BatteryStatsHelper.load(BatteryStatsHelper.java:1023)
at com.android.internal.os.BatteryStatsHelper.getStats(BatteryStatsHelper.java:258)
at com.android.settings.fuelgauge.BatteryInfo.getBatteryInfo(BatteryInfo.java:151)
at com.android.settings.fuelgauge.BatteryInfo.getBatteryInfo(BatteryInfo.java:145)
梳理下整体调用流程
1
2
3
4
5
6
7
客户端 -> 代理服务端 (Proxy)-> 服务端(Binder) -> native 层 Binder -> Binder 驱动
【java 层 Client 发起请求】BatteryStatsHelper#getStats() ->
【java 层服务 Proxy】IBatteryStats.Stub.Proxy#getStatisticsStream() ->
【java 层 Binder】BinderProxy#transact() -> BinderProxy#transactNative() ->
【native 层 BinderProxy】android_util_Binder.cpp::android_os_BinderProxy_transact() -> BpBinder.cpp::transact() ->
【native 层 IPCThreadState】IPCThreadState.cpp::transact() -> IPCThreadState.cpp::waitForResponse() -> IPCThreadState.cpp::talkWithDriver() ->
【native 层 Binder 驱动】通过 ioctl() 与 binder 驱动交互
参考资料
- 《深入理解Android卷1》(邓凡平)第六章:深入理解 Binder