Binder机制分析(2)——从MediaService中看Binder的实现和使用(1)
来源:互联网 发布:Vb大漠插件注册 编辑:程序博客网 时间:2024/03/29 13:25
本文是对《Android技术内幕-系统卷》第三章的摘抄和整理。
1. MediaService入口, 获取ServiceManager
下面我们就从MediaService的源码入手进行分析,首先,MediaService的入口函数的实现位于“framework\base\media\mediaServer\main_mediaserver.cpp”。int main(int argc, char* argv)
{
//获得ProcessState实例
sp<ProcessState> proc(ProcessState::self());
//得到一个ServiceManager对象
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
//初始化MediaService服务
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
//启动进程的线程池
ProcessState::self()->startThreadPool();
//将自己加入到线程池
IPCThreadState::self()->joinThreadPool();
}
1.1 defaultServiceManager()的实现
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
//创建gDefaultServiceManager
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
这里采用了singleton模式,如果全局的gDefaultServiceManager不为NULL,则直接返回;否则,创建一个gDefaultServiceManager。
1.2 getContextObject()的实现
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
if (supportsProcesses()) {
return getStrongProxyForHandle(0);
} else {
return getContextObject(String16("default"), caller);
}
}
1.3 getStrongProxyForHandle的实现
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
// We need to create a new BpBinder if there isn't currently one, OR we
// are unable to acquire a weak reference on this current one. See comment
// in getWeakProxyForHandle() for more info about this.
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
// This little bit of nastyness is to allow us to add a primary
// reference to the remote proxy when this team doesn't have one
// but another team is sending the handle to us.
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
将创建过程交给ProcessState::getStrongProxyForHandle()函数来实现,第一次进入该函数则会创建一个BpBinder对象并返回。
1.4 interface_cast的实现
大家可能会疑惑,明明创建的是一个BpBinder对象,为什么最后却通过interface_cast函数强制转换为IServiceManager。
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
替换INTERFACE:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
其中,INTERFACE对应于IServiceManager,因此我们需要继续找到IServiceManager::asInterface(...)的实现。在IServiceManager中我们可以看到一个如下所示的宏:
DECLARE_META_INTERFACE(ServiceManager);
1.5 DECLARE_META_INTERFACE分析
#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:
#define DECLARE_META_INTERFACE(INTERFACE)
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();
1.6 IMPLEMENT_META_INTERFACE分析
IMPLEMENT_META_INTERFACE(ServiceManager, "Android.os.IServiceManager"); //IServiceManager.cpp
#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() { }
替换INTERFACE:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
const Android::String16 IServiceManager::descriptor("Android.os.IServiceManager");
const android::String16&
IServiceManager::getInterfaceDescriptor() const {
return IServiceManager::descriptor;
}
Android::sp<IServiceManager> ServiceManager::asInterface(
const Android::sp<android::IBinder>& obj) //实际上obj = BpBinder(0);
{
Android::sp<IServiceManager> intr;
if (obj != NULL) {
intr = static_cast<IServiceManager*>(
obj->queryLocalInterface(
IServiceManager::descriptor).get());
if (intr == NULL) {
intr = new BpServiceManager(obj); //实际上obj = BpBinder(0);
}
}
return intr;
}
IServiceManager::IServiceManager() { }
IServiceManager::~IServiceManager() { }
1.7 asInterface的实现
该函数首先会根据描述符去查找本地的Interface,如果没有查找到,则会执行“new Bp##INTERFACE(obj);”,实际上就是创建了一个BpServiceManager实例。
因为这个命名也以Bp开头,也许它与上一节介绍的Binder机制的服务器代理对象有关,其实BpServiceManager就是ServiceManager的Binder代理对象。
1.8 BpServiceManager实现
在IServiceManager.cpp中可以找到BpServiceManager的实现:
BpServiceManager(const sp<IBinder>& impl) //实际上impl = BpBinder(0);
: BpInterface<IServiceManager>(impl)
{
}
这里的impl就是之前通过ProcessState::getContextObject创建的BpBinder对象。接着进入BpInterface的构造函数,它位于IInterface.h中:
inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote) //实际上remote = BpBinder(0);
: BpRefBase(remote)
{
}
最终会进入BpRefBase的构造函数,它位于Binder.cpp中:
BpRefBase::BpRefBase(const sp<IBinder>& o) //实际上o = BpBinder(0);
: mRemote(o.get()), mRefs(NULL), mState(0) //实际上mRemote = BpBinder(0);
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
if (mRemote) {
mRemote->incStrong(this); //Removed on first
mRefs = mRemote->createWeak(this); //Held for our entire
}
}
o.get()实际上就是之前通过ProcessState::getContextObject创建的BpBinder对象,即mRemote指向BpBinder对象。也就是说,“sp<IServiceManager> sm = defaultServiceManager();”语句返回的实际上是BpServiceManager,它的remote对象是BpBinder,传入的handle参数是0。
得到了BpServiceManager对象后,我们就可以通过Binder与ServiceManager进行交互了。
2. 添加Service到ServiceManager:
2.1 MediaPlayerService::instantiate()分析
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
MediaPlayerService构造函数:
MediaPlayerService::MediaPlayerService()
{
LOGV("MediaPlayerService created");
mNextConnId = 1;
}
初始化过程为:首先,构造一个MediaPlayerService。
然后,通过defaultServiceManager()获得之前创建的BpServiceManager,并调用其addService函数。
而MediaPlayerService又继承自BnMediaPlayerService,实际上就是MediaPlayerService服务,对应于Binder机制中的服务端。
2.2 BpServiceManager::addService的实现
virtual status_t addService(const String16& name, const sp<IBinder>& service) //service就是BnMediaPlayerService
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); //通过宏DECLARE_META_INTERFACE所定义的描述符"Android.os.Iservice Manager"。
data.writeString16(name); //name就是"media.player"
data.writeStrongBinder(service); //service就是BnMediaPlayerService
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); //remote()返回mRemout,也就是BpBinder(0)
return err == NO_ERROR ? reply.readInt32() : err;
}
首先调用writeInterfaceToken写入Interface的名称IServiceManager::getInterfaceDescriptor(),写入的名称实际上就是前面在IServiceManager中,
然后,通过writeString16写入服务的名称,根据参数可以知道该服务的名称为media.player;
最后,通过writeStrongBinder写入服务,也就是上面所说的MediaPlayerService,即BnMediaPlayerService。
准备好要发送的命令包后,通过remote()获得其mRemote对象(前面分析过,该对象实际上就是在defaultServiceManager()中创建的BpBinder对象,也就是BpBinder(0));
调用transact函数来发送命令包,发送的命令为添加服务ADD_SERVICE_TRANSACTION。
2.3 IPCThreadState::self()->transact
BpBinder::transact最终会调用 IPCThreadState::self()->transact来发送数据。
而在IPCThreadState中,最终还是通过writeTransactionData函数来完成数据的发送的。
发送之后,waitForResponse函数会等待反馈的结果,在writeTransactionData中会将要发送的数据整理为一个binder_transaction_data结构体(请参见Binder驱动的部分)。
直到进入talkWithDriver函数中才会真正开始利用Binder驱动来进行通信。对于驱动的操作,当然就是ioctl了。talkWithDriver函数中的发送片段如代码清单3-60所示。
talkWithDriver的实现片段
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
BpServiceManager发送的信息应该由BnServiceManager来接收,但是Android中并没有BnServiceManager。
因此,具体的接收操作会由Service Manager来完成。具体操作流程请参考上一篇关于Service Manager的实现,也就是其中的svcmgr_handler函数。
3. 总结
1)通过ProcessState::self()函数获得ProcessState对象,并打开Binder设备。
2)通过defaultServiceManager得到BpServiceManager实例。
3)通过MediaPlayerService::instantiate()得到MediaPlayerService服务BnMediaPlayer Service,并通过BpServiceManager::addService将MediaPlayerService服务加入到Service Manager的list中。
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(1)
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(1)
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(1)
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(1)
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(2)
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(2)
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(2)
- Binder通信二(MediaService理解Binder机制)
- Binder机制分析(1)——Binder结构简介
- Binder机制分析(1)——Binder结构简介
- Binder机制分析(1)——Binder结构简介
- 2.6 Binder机制(MediaService)
- Binder机制分析(3)—— 实现自己的Service
- Binder机制分析(3)—— 实现自己的Service
- Binder机制分析(3)—— 实现自己的Service
- Binder机制(1)
- Android Binder机制の设计与实现1-3(引言/面向对象的 Binder IPC/Binder 通信模型)
- android binder机制之——(我是binder实例)
- 重学数据结构008——AVL树
- 深入了解字符集和编码
- Chip in mario(JAVA GAME)
- android不让弹出键盘挡住View
- 关于 for update
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(1)
- JQUERY获取text,areatext,radio,checkbox,select值
- 看到两个写的很好的关于字符集,编码的文章,推荐大家看看
- Binder机制分析(2)——从MediaService中看Binder的实现和使用(2)
- Web布局中的几种宽高自适应
- sql分页
- Linux中的通知链技术
- linux 查看端口占用进程ID
- Hibernate的连接查询