本文学习拜读自邓凡平老师的 《深入理解Android卷1》
一 MediaServer 之 Server端
1.1 :步骤一
1.2 :步骤二
- 1.2.1 defaultServiceManager()分析
- 1.2.2 BpBinder 与 IServiceManager简析
- 1.2.2.1 BBinder简析
- 1.2.2.2 IServiceManager简析
- 1.2.2.2.1 定义业务逻辑
- 1.2.2.2.2 业务与通信挂钩
1.3:步骤三
- 1.3.1 将通信的工作交给 BpBinder
- 1.3.2 BpBinder->transact()分析
- 1.3.3 分析 IPCThreadState
二 MediaServer 之 Client端
实例解读 Binder,选择 MediaServer作为分析对象。以main_mediaserver.cpp作为切入点分析,如下:
一 MediaServer 之 Server端
概述:
在基于Binder通信的 C/S 架构体系中,除了 C/S 架构所包括的 Client端和Server端外,Android还有一个全局的 ServiceManager端,它的作用是管理系统中的各种服务(Servicer)。Client、Server和ServiceManager这三者之间的交互关系如图所示:
小结
-
1
Server进程要先注册一些 Service 到 ServiceManager中,所以Server是ServiceManager的客户端,而ServiceManager就是服务端了。 -
2
如果某个Client进程要使用某个Service必须先到ServiceManager中获取该Service 的相关信息,所以Client是ServiceManager的客户端。 -
3
Client根据得到的Service信息与Service所在server进程建立通信通路,然后就可以直接与Service交互了,所以Client也是Server的客户端。
main_mediaserver.cpp 概述
frameworks/av/media/mediaserver/main_mediaserver.cpp
......
int main(int argc __unused, char **argv __unused)
{
InitPlayer();
signal(SIGPIPE, SIG_IGN);
/*
* 1. 获取一个 ProcessState 实例
*/
sp<ProcessState> proc(ProcessState::self());
/*
* 2. MS作为 ServiceManager的客户端,需要向ServiceManager注册服务,调用 defaultServiceManager() 得到一个 IServiceManager
*/
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
/*
* 3. 多媒体系统的 MediaPlayer服务
*/
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
registerExtensions();
/*
* 4. 创建一个线程池
*/
ProcessState::self()->startThreadPool();
/*
* 5. 加入线程池
*/
IPCThreadState::self()->joinThreadPool();
}
1.1 :步骤一
步骤一
/*
* 1. 获取一个 ProcessState 实例
*/
功能 :
- 1 打开 Binder 设备
- 2 映射内存起始地址
sp<ProcessState> proc(ProcessState::self())
1.1
//self函数采用单例模式,即每个进程只有一个 ProcessState对象。
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
//gProcess是一个全局变量,程序刚开始执行,gProcess一定为空。
if (gProcess != NULL) {
return gProcess;
}
//创建一个 ProcessState 对象,并赋值给 gProcess
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
1.2 ProcessState的构造
frameworks/native/libs/binder/ProcessState.cpp
static int open_driver()
{
//dakai Binder设备
int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
if (fd >= 0) {
int vers = 0;
//ioctl 查询版本号
status_t result = ioctl(fd, BINDER_VERSION, &vers);
if (result == -1) {
ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
close(fd);
fd = -1;
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
ALOGE("Binder driver protocol does not match user space protocol!");
close(fd);
fd = -1;
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
//ioctl 确认最大线程数 :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 '/dev/binder' failed: %s\n", strerror(errno));
}
return fd;
}
//ProcessState的构造函数
ProcessState::ProcessState()
: mDriverFD(open_driver()) // 打开 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) {
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
if (mVMStart == MAP_FAILED) {
// *sigh*
ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD = -1;
}
}
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
1.2 :步骤二
步骤二
/*
MS作为 ServiceManager的客户端,需要向ServiceManager注册服务,调用 defaultServiceManager()得到一个 IServiceManager 对象
*/
功能
- 1 defaultServiceManager()函数最后是创建了一个 BBinder,并且最终返回的是 IServiceManager::asInterface(obj)。
1.2.1 defaultServiceManager()分析
frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
/*
* 创建 gDefaultServiceManager,此处调用了 ProcessState::self()->getContextObject(NULL),并且参数为NULL
* 将 BpBinder* 类型强制装换成 IServiceManager* 类型
*/
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
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
*/
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
简单的整理思路:
sp<IServiceManager> defaultServiceManager()
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
b = new BpBinder(handle);
等价于 :
sp<IServiceManager> defaultServiceManager()
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL))
b = new BpBinder(handle);
等价于 :
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));
而 interface_cast的实现如下:
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
所以 interface_cast() 相当于
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
故 defaultServiceManager()函数 最终返回的是 IServiceManager::asInterface(obj)!!!
也就是说 defaultServiceManager()函数最后是创建了一个 BBinder,并且最终返回的是 IServiceManager::asInterface(obj),
问题
1 什么是BBinder?
2 什么是IServiceManager?
3 IServiceManager::asInterface(obj)是什么?
1.2.2 BpBinder 与 IServiceManager简析
1.2.2.1 BBinder简析:
BpBinder和BBinder都是Android系统中与Binder通信相关的代表,他们都是从 IBinder类中派生而来的。
BpBinder是客户端用来与Server交互的代理类,p即Proxy的意思,
frameworks\native\libs\binder\BpBinder.cpp
BpBinder::BpBinder(int32_t handle)
: mHandle(handle)
, mAlive(1)
, mObitsSent(0)
, mObituaries(NULL)
{
ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
// IPCThreadState!!
IPCThreadState::self()->incWeakHandle(handle);
}
小发现:发现 BpBiner和BBinder这两个类没有任何地方操作 ProcessState打开的那个 /dev/binder设备,也就是说,这两个类并没有直接和Binder设备直接交互
1.2.2.2 IServiceManager简析
上面提到的, IBinder家族的 BpBinder和BBinder是与通信业务相关的,那么业务层的逻辑是如何架构在Binder机制上的呢?
1.2.2.2.1 定义业务逻辑:
frameworks\native\include\binder\IServiceManager.h
class IServiceManager : public IInterface
{
public:
//无比关键的宏!!!! 声明元接口
DECLARE_META_INTERFACE(ServiceManager);
/*
* ServiceManager 所提供的业务函数
*/
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) = 0;
virtual Vector<String16> listServices() = 0;
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
};
1.2.2.2.2 业务与通信挂钩
Android巧妙的通过 DECLARE_META_INTERFACE 和 IMPLENT 宏,将业务和通信牢牢的钩在一起。DECLARE_META_INTERFACE 和 IMPLEMENT_META_INTERFACE这两个宏定义如下
frameworks/native/include/binder/IInterface.h
宏 DECLARE_META_INTERFACE :声明
/* DECLARE_META_INTERFACE(FregService);
* 1. 为 FregService 类定义了一个静态成员变量 descriptor,用来描述接口名称,可以通过成员函数getInterfaceDescriptor()来获取。
* 2. 同时定义了一个静态成员函数 asInterface(),用来讲一个 IBinder对象装换为一个IFregService接口。
* 3. 最后定义了构造函数和析构函数
*/
#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();
则 DECLARE_META_INTERFACE(IServiceManager);内容如下:
/*
* 定义一个描述字符串
*/
static const android :: String16 descriptor;
/*
* 定义一个asInterface函数
*/
static android::sp<IServiceManager>
asInterface(const android::sp<android::IBinder>& obj)
/*
* 定义一个 getInterfaceDescriptor函数,用于返回 descriptor字符串。
*/
virtual const android::String16& getInterfaceDescriptor() const;
/*
* 定义 构造函数 和 析构函数
*/
IServiceManager();
virtual ~IServiceManager();
宏 IMPLEMENT_META_INTERFACE 定义
IMPLEMENT_META_INTERFACE(IFregService, "hr.ma.IFregService");
/*
* 1. 将 IFregService类的静态成员变量 descriptor 设置为 " hr.ma.IFregService "
* 2. 实现了 IFregService类的构造函数和析构函数,是空函数
* 3. 实现了成员函数 getInterfaceDescriptor() ,用来获取一个IFregService类的描述符,即 descriptor
* 4. 实现了 asInterface(),用来将一个 IBinder对象装换为一个 IFregService接口。
*/
#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 是如何使用这些宏的呢?如下:
frameworks\native\libs\binder\IServiceManager.cpp
...
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
...
打开如下:
static const android::String16 IServiceManager::descriptor(android.os.IServiceManager);
/*
* 实现 getInterfaceDescriptor 函数
*/
const android::String16& IServiceManager::getInterfaceDescriptor() const
{
/* 返回字符串 descriptor,值为 "android.os.IServiceManager" */
return IServiceManager::descriptor;
}
/*
* 实现 asInterface函数, 将 BpBinder 指针转换为一个 IServiceManager接口。
*/
static android::sp<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) {
//obj 使我们刚才创建的那个 BpBinder(0)!!!!!!
intr = new BpServiceManager(obj);
}
}
return intr;
}
/*
* 实现构造函数和析构函数
*/
IServiceManager::IServiceManager(){}
IServiceManager:: ~IServiceManager() {}
则到此为止 defaultServiceManager()函数最后是创建了一个 BBinder,并且最终返回的是 IServiceManager::asInterface(obj),返回的是一个 BpServiceManager 对象!
1.3:步骤三
步骤三
/*
* 3. 多媒体系统的 MediaPlayer服务
*/
1.3.1 将通信的工作交给 BpBinder
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
// defaultServiceManager()函数最后返回的是一个 BpServiceManager 对象!
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
frameworks\native\libs\binder\IServiceManager.cpp
/* 功能: 将通信的工作交给 BpBinder
* 1 将请求的数据打包成 data
* 2 将打包好的数据 传给 BpBinder 的 transact()函数
*/
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
//数据包
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
//remote()返回一个 mRemote指针 指向的是BpBinder类,transact()与设备驱动交互
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
1.3.2 BpBinder->transact()分析
在BpBinder中确实找不到任何与Binder设备交互的地方。那他是如何参与通信的呢?答案就在 BpBinder->transact() 中。
rk3288_7.1_mid\frameworks\native\libs\binder\BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
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;
}
1.3.3 分析 IPCThreadState
IPCThreadState 是进程中通信中的关键,代码如下:
frameworks\native\libs\binder\IPCThreadState.cpp
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS) {
restart:
const pthread_key_t k = gTLS;
/*
TSL 是 Thread Local Storage(线程本地存储空间)的简称,我们在这里只需要记住:TSL线程本地存储空间是每个线程都有的。而且线程间不共享这些空间。
可以通过 pthread_getspecific()/pthread_setspecific() 可以获取/设置这些空间中的内容。从线程本地存储空间中获得保存在其中的 IPCThreadState对象。
*/
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
//创建一个 IPCThreadState 对象。
return new IPCThreadState;
}
if (gShutdown) {
ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
return NULL;
}
pthread_mutex_lock(&gTLSMutex);
if (!gHaveTLS) {
int key_create_value = pthread_key_create(&gTLS, threadDestructor);
if (key_create_value != 0) {
pthread_mutex_unlock(&gTLSMutex);
ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
strerror(key_create_value));
return NULL;
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex);
goto restart;
}
/*
* 构造函数
*/
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
mMyThreadId(gettid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
//在构造函数中,把自己设置到线程本地存储空间中去
pthread_setspecific(gTLS, this);
clearCaller();
// mIn、mOut是两个 Parcel。把它看成发送命令和接受命令的缓冲区即可。
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
//注意 handle值为0,代表了通信的目的端
//很明显的流程: 先发送数据,然后等待结果!
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
......
/*
第一个参数 BC_TRANSACTION,他是应用程序向Binder设备发送消息的消息码,而Binder设备向应用程序回复的消息以BR_ 开头。
*/
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
......
err = waitForResponse(reply);
......
return err;
}
这样,每个线程都有一个 IPCThreadState,每个 IPCThreadState 中都有一个 mIn、一个mOut,其中,mIn是用来接收来自Binder设备的数据,mOut则是用来存储发往 Binder设备的数据的。
现在我们知道 BpBinder的transact()调用了 IPCThreadState的transact()函数,这个函数实际完成了与Binder设备通信的工作。
二 MediaServer 之 Client端
一个Client 想要得到某个Service的信息时,就必须先和 ServiceManager打交道,通过调用 getService()函数来获取对应的 Serviced 信息。
查询 ServiceManager
/*
getMediaPlayerService()函数通过与 ServiceManager 通信,获得一个能够与 MediaPlayerService 通信的 BpBinder
然后再通过 interface_cast,装换成一个 BpMediaPlayerService
*/
/*static*/const sp<IMediaPlayerService>
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
/*
向 ServiceManager 查询对应服务的信息,返回BpBinder
*/
binder = sm->getService(String16("media.player"));
if (binder != 0) {
break;
}
ALOGW("Media player service not published, waiting...");
/*
如果 ServiceManager 上还没有注册对应的服务,则需要等待,知道对应的服务注册到 ServiceManager 中为止
*/
usleep(500000); // 0.5 s
} while (true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
/*
通过 interface_cast 将这个 binder 转化成 BpMediaPlayerService,binder中 handle 标识的一定是目的端 MediaPlayerService
*/
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}
有了 BpMediaPlayerService,就能够使用任何 IMediaPlayerService 提供的业务逻辑函数了。