本篇文章分析mediaserver的启动过程中获取servicemanager以及注册服务的过程。希望这篇文章能够帮助大家弄清楚系统服务对BpBinder的封装过程,同时为之后分析Binder通信过程做好通信数据上的准备,即让大家知道Binder通信中发送的数据内容是什么。
我们从media server的主函数开始。
main_mediaserver
//\frameworks\av\media\mediaserver\main_mediaserver.cpp
int main(int argc __unused, char **argv __unused)
{
signal(SIGPIPE, SIG_IGN);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());//获取service manager
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
MediaPlayerService::instantiate();//注册服务
ResourceManagerService::instantiate();
registerExtensions();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
总结一下就是获取service manager并向其发送注册请求后,进入线程池循环。这里我们只要看service manager是怎么获取的,以及注册服务的流程即可。
defaultServiceManager获取sm业务封装类
defaultServiceManager的作用是返回service manager的业务封装类。
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
首次调用defaultSericeManager()时,该函数首先会调用ProcessState::self()->getContextObject(NULL),然后将返回结果传给模板函数interface_cast()。
getContextObject()的作用是返回ServiceManager的通信代理类BpBinder,而interface_cast()的作用是将BpBinder封装在业务类BpServiceManager中。可以这样理解这两个类,BpBinder负责完成通信工作,也就是将传进来的数据发送给ServiceManager。而BpServiceManager实现业务函数,也就是根据业务需要构造不同的数据包,然后调用BpBinder相关函数发送。用于通信的还有另外一个类BBinder,关于它的功能我们之后再介绍。
getContextObject得到sm的BpBinder
我们看getContextObject做了什么。
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
以0为参数调用了getStrongProxy。
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
//从ProcessState的vector成员mHandleToObject找到handle值对应的handle_entry
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
//如果handle_entry的Ibinder成员还未赋值
if (b == NULL || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {//传进来的参数为0,会进入这个分支
Parcel data;
//向service manager发送测试数据
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
b = new BpBinder(handle); //由handle值构造BpBinder
e->binder = b;//放进handle_entry中。
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;//返回BpBinder(handle)
}
总结一下就是构造了根据handle值构造BpBinder,放进ProcessState的vector成员mHandleToObject中,并且返回该BpBinder。
里面特别注意的有两个点,第一个点是传进来的参数handle。handle值标识了一个服务端,Binder驱动就是根据该值来找到通信目标的。另一个点就是handle值构造的BpBinder,它是Binder通信代理类(我一直不理解什么是代理类),完成通信工作。
另外,这里传进来的handle值为0,代表service manager。一般而言,对所有进程来说,service manager的handle值都为0。知道服务端的handle值之后才能构造BpBinder来发送Binder通信数据。这里已经构造了service manager的BpBinder,之后便可以向service manager请求服务,例如请求得到其它服务的handle值。
interface_cast封装BpBinder
在defaultServiceManager中,通过getContextObject获取BpBinder后,将其传给了interface_cast进行封装,最终返回一个IServiceManager类。
// \frameworks\native\include\binder\IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
所以,defaultServiceManager()中就相当于调用了IServiceManager::asInterface(),然而,在IServiceManager中的头文件和cpp文件中却找不到asInterface(),看了书才知道,其实这个函数的申明是藏在了头文件中的DECLARE_META_INTERFACE(ServiceManager)宏定义里面。而定义藏在cpp文件的IMPLEMENT_META_INTERFACE(ServiceManager, “android.os.IServiceManager”)宏定义里面。长见识了。
DECLARE_META_INTERFACE的定义如下:
// \frameworks\native\include\binder\IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE) \
static const android::String16 descriptor; \
static android::sp<I##INTERFACE> asInterface( \
const android::sp<android::IBinder>& obj); \
virtual const android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE();
将ServiceManager代入,就相当于:
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();
IMPLEMENT_META_INTERFACE的定义如下:
// \frameworks\native\include\binder\IInterface.h
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<I##INTERFACE> intr; \
if (obj != 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和"android.os.IServiceManager"代入IMPLEMENT_META_INTERFACE,可以得到:
const android::String16 IServiceManager::descriptor("android.os.IServiceManager");
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
android::sp<IServiceManager> IServiceManager::asInterface(
const android::sp<android::IBinder>& obj)
{
android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
我们主要关注asInterface()函数,可以看到,这个函数返回的是一个BpServiceManager对象,传入的obj(根据我们之前的分析,obj即是BpBinder指针)用来构造这个BpServiceManager对象。
这两个宏不仅在IServiceManager里面可以找到,在其它服务类比如IMediaPlayer中也能看到,只不过传入DECLARE_META_INTERFACE的参数变成MediaPlayer,传入IMPLEMENT_META_INTERFACE的参数变成MediaPlayer,和"android.media.IMediaPlayer"。所以可以推测,系统中的每一个Service,都有一个Bp+服务名的类,例如BpServiceManager,BpMediaPlayer,而这些类需要用BpBinder指针来构造,而当进行通信时,就是通过这个BpBinder指针调用相关函数来进行的。我们继续看BpServiceManager的构造函数。
我们继续看BpServiceManager的构造函数。
// \frameworks\native\libs\binder\IServiceManager.cpp
BpServiceManager(const sp<IBinder>& impl)
: BpInterface<IServiceManager>(impl)
{
}
构造函数将BpBinder指针传给了父类BpInterface的构造函数。
// \frameworks\native\include\binder\IInterface.h
//原始定义
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote){}
//代入IServiceManager,注意,代入的不是BpServiceMaNager
inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote){}
BpBinder指针又被传给了父类BpRefBase的构造函数,而在BpRefBase的构造函数中,该值被用来初始化mRemote成员。
service manager获取小结
如图所示:
最终返回了BpServiceManager(IServiceManager)。其中BpServiceManager的mRemote成员就是BpBinder指针。而BpBinder对应的BBinder又是怎么封装的呢?这里使用《深入理解Android》中的一张图来解释:
可以看到BBinder直接被业务类BnServiceManager继承。这里需要注意的是BpBinder和BBinder这两个用于通信的类的不同封装方式,一个是作为成员变量封装在业务类中,一个是作为父类被业务类所继承。我们会在后面的文章中具体介绍这两个通信类完成的工作。
另外,虽然我只分析了ServiceManager的封装,但其实几乎所有的系统服务都采用相同的封装方式,它们都有Bp+服务名和Bn+服务名的两个类,继承关系也和上面介绍的基本相同。
MediaPlayerService::instantiate注册服务
//\frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
调用了BpServiceManager的addService。传入的参数是服务名media.player和MediaPlayerService类,在前面的图中我们知道,MediaPlayerService其实是BBinder的继承类。
//\frameworks\native\libs\binder\IServiceManager.cpp
//addService(String16("media.player"), new MediaPlayerService());
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
Parcel data, reply;
//将服务名和MediaPlayerService写入Parcel
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
//在interface_cast分析中我们知道BpServiceManager的remote成员是handle值
//为0的BpBinder,这里相当于BpBinder->transact。该函数完成数据的发送
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
总结一下,addService把服务吗和MediaPlayerService类写进数据包Parcel之后,通过BpBinder->transact发送给了service manager。
本篇文章到此结束。下篇文章将分析Binder中的数据包类Parcel。