zoukankan      html  css  js  c++  java
  • [置顶] Android开发之MediaPlayerService服务详解(一)

           前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState。ProcessState负责打开Binder
    驱动,每个进程只有一个。而 IPCThreadState负责提供与Binder通信相关的接口,每个线程有一个。下面我们通过具体
    示例MediaPlayerService来分析我们应用程序中怎么通过Binder通信的。


    frameworks/base/media/mediaserver/main_mediaserver.cpp

    int main(int argc, char*argv[])
    {
    	sp<ProcessState> proc(ProcessState)::self();	// 获得ProcessState在构造函数中打开binder驱动
    	sp<IServiceManager> sm = defaultServiceManager();
    	MediaPlayService::instantiate();
    	ProcessState::self()->startThreadPool();
    	IPCThreadState::self()->joinThreadPool();
    }

    1)获得ServiceManager的代理BpServiceManager

    sp<IServiceManager> sm = defaultServiceManager();
    sp<IServiceManager> defaultServiceManager()
    {
    	if(gDefaultServiceManager != NULL) return gDefaultServiceManager;
    	{
    		AutoMutex -l(gDefaultServiceManagerLock);
    		if(gDefaultServiceManager == NULL)
    			gDefaultServiceManager = interface_cast<IServiceManager>(
    				ProcessState::self()->getContextObject(NULL));
    	}
    	return gDefaultServiceManager;
    }

    这里又是一个单例模式,每个进程只需要一个BpServiceManager代理,通过interface_cast获得。
    首先看看ProcessState::self()->getContextObject(NULL)

    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)) {
    			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;
    }
    struct handle_entry{
    	IBinder* binder;
    	RefBase::weakref_type* refs;
    }

    ProcessState::handle_entry* ProcessState::lookupHandleLocked()从数组mHandleToObject里面根据handle索引,查找
    一个handle_entry结构体。然后根据传入的句柄handle这里为0,表示ServiceManager,new一个BpBinder
    所以现在相当于:
    gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0));

    现在我们看看interface_cast是什么?

    frameworks/base/include/binder/IInterface.h
    template<typename INTERFACE>
    inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
    {
    	return INTERFACE::asInterface(obj);
    }
    等价于:
    inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)
    {
    	return IServiceManager::asInterface(obj);
    }
    继续我们跟到IServiceManager里面去:
    frameworks/base/include/binder/IServiceManager.h
    class IServiceManager:public IInterface
    {
    public:
    	DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!!
    	virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0;
    	virtual sp<IBinder> getService(const String16& name) const = 0;
    }
    #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();
    替换之后就是:
    	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();
    都是一些函数声明,既然有声明的地方,肯定有实现的地方了。
    #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() { }                                   
    继续替换:
    {
        const android::String16 IServiceManager::descriptor(NAME);             
        const android::String16&                                            
               IServiceManager::getInterfaceDescriptor() const {              
            return IServiceManager::descriptor;                                
        }                                                                   
        android::sp<IServiceManager> IServiceManager::asInterface(                
                const android::sp<android::IBinder>& obj)   // 参数为new 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);     // 原来在这里new 了一个BpServiceManager对象                     
                }                                                           
            }                                                               
            return intr;                                                    
        }                                                                   
        IServiceManager::IServiceManager() { }                                    
        IServiceManager::~IServiceManager() { }                                   
    }

    总结:根据句柄handle 0 创建一个new BpBinder(0),根据这个BpBinder创建了一个BpServiceManager代理。

    下面来看看BpServiceManager代理:

    class BpServiceManager : public BpInterface<IServiceManager>
    {
    public:
    	BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml)
    	{}
    } 

    这里BpInterface是一个模板类,表示这里BpServiceManager同时继承与BpInterface和IServiceManager类

    template<typename INTERFACE>
    class BpInterface : public INTERFACE, public BpRefBase
    {
    public: BpInterface(const sp<IBinder>& remote);
    ...
    }
    调用了基类BpInterface构造函数:
    BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote)
    {}
    //这里的remote就是刚刚的new BpBinder(0)
    BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0)
    {
    }
    
    

    2)添加服务 MediaPlayerService::instantiate();

    frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cpp
    void MediaPlayerService::instantiate()
    {
    	defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService);
    }

    defaultServiceManager()返回的是刚创建的BpServiceManager,调用add函数。
    BpMediaPlayService作为服务代理端,那么BnMediaPlayerService一定是实现端,MediaPlayerService继承于
    BnMediaPlayerService,实现了真正的业务函数。

    来看看BpServiceManager的addService()函数:

    virtual status_t addService(const String16& name, const sp<IBinder>& service)
    {
    	Parcel data, reply;
    	data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor());	// android.os.IServiceManager
    	data.writeString16(name);	// media.player
    	data.writeStrongBinder(service);	// 也就是MediaPlayerService
    	status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    	return err == NO_ERROR ? reply.readInt32() : err;
    }

    这里remote()就是前面创建的BpBinder(0)对象。

    status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
    	IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
    }
    status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
    	// 发送ADD_SERVICE_TRANSACTION请求
    	writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    	if(reply)	// 等待响应
    		waitForResponse(NULL, reply);
    }
    
    status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, 
    		uint32_t code, const Parcel& data, status_t *statusBuffer)
    {
    	// cmd	BC_TRANSACTION	应用程序向BINDER发送的命令
    	binder_transaction_data tr;
    	tr.target.handle = handle;	// 0
    	tr.code = code;			// ADD_SERVICE_TRANSACTION
    	tr.flags = binderFlags;
    	// 把命令和数据一起发送到 Parcel mOut中
    	mOut.writeInt32(cmd);
    	mOut.write(&tr, sizeof(tr));
    }
    status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult)
    {
    	int32_t cmd;
    	
    	while(1) 
    		talkWithDriver();
    		cmd = mIn.readInt32();
    		switch(cmd) {
    			case BR_TRANSACTION_COMPLETE:
    				...
    				break;
    		}
    	{
    	return err;
    }
    status_t IPCThreadState::talkWithDriver(bool doReceive)
    {
    	binder_write_read bwr;
    	
    	bwr.write_size = outAvail;
    	bwr.write_buf = (long unsigned int)mOut.data();	// 写入mOut的数据
    	bwr.read_size = mIn.dataCapacity;
    	bwr.read_buffer = (long unsigned int)mIn.data();
    	ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr);	// 把mOut写到Binder,并读取mIn数据
    }


     

    3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool()
    进入线程循环talkWithDriver 等待客户端Client请求,从Binder读取命令请求进行处理。

    到现在为止MediaPlayerService的服务端已经向服务总管ServiceManager注册了,下面我们看看客户端是如何获得服务的代理并和服务端通信的。
    我们以MediaPlayer的业务函数decode解析播放一个URL为例

    sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...)
    {
    	sp<IMemory> p;
    	const sp<IMediaPlayerService>& service = getMediaPlayerService();	// 获得BpMediaPlayerSerivce代理
    	if(service != 0)
    		p = service->decode(url, ....);
    	return p;
    }

    这里我们主要分析getMediaPlayerService,客户端是如何向ServiceManager总管查询服务并获得代理的。

    sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService()
    {
    	sp<IServiceManager> sm = defaultServiceManager(); // 生成一个BpServiceManager代理对象
    	sp<IBinder> binder;
    	do {
    		binder = sm->getService(String16("media.player"));
    		if(binder != 0)
    			break;
    		usleep(500000)
    	} while(true);
    	sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    	return sMediaPlayerService;
    }

    1)首先获得BpServiceManager的代理,然后调用getService()函数向服务总管ServiceManager查询服务。
    frameworks/base/libs/binder/IServiceManager.cpp

    class BpServiceManager : public BpInterface<IServiceManager>
    {
    public:
    	virtual sp<IBinder> getService(const String16& name) const
    	{
    		for(n = 0; n < 5; n++) {
    			sp<IBinder> svc = checkService(name);	// 调用checkService函数
    			if(svc != NULL) return svc;
    			sleep(1);
    		}
    		return NULL;
    	}
    	virtual sp<IBinder> checkService(const String16& name) const 
    	{
    		Parcel data, reply;
    		data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    		// 首先调用data.writeInt32(IPCThreadState::self()->getStrictModePolicy())
    		// 然后再写入android.os.IServiceManager
    		data.writeString16(name);	// 写入 media.player
    		remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    		return reply.readStrongBinder();
    	}
    }

    这里首先将请求打包成Parcel各式,然后调用remote()->transact()函数,前面我们分析过BpServiceManager::remote()返回
    的就是前面new BpBinder(0)对应句柄为ServiceManager。继续去BpBinder中寻找实现代码:
    frameworks/base/libs/binder/BpBinder.cpp

    status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
    	IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
    }

    最后调用的IPCThreadState的transact()函数,IPCThreadState是专门提供通过Binder进程间通信的接口的。

    status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
    	// 填充binder_transaction_data 结构体,写入到mOut中去
    	writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    	
    	// 调用talkWithDriver() 将mOut写到Binder驱动,并从Binder驱动读取mIn数据
    	waitForResponse(reply);
    }

    首先通过writeTransactionData函数来填充mOut结构体,mOut里面内容为:
     mOut.writeInt32(BC_TRANSACTION);
     mOut.write(&tr, sizeof(tr));
    这里binder_transaction_data tr内容为:
     tr.target.handle = 0; // 表面是发往ServiceManager的
     tr.code = CHECK_SERVICE_TRANSACTION;
     tr.flags = 0;
    tr.data内容为:
     data.writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
     data.writeString16("android.os.IServiceManager");
     data.writeString16("media.player");
    根据前面Android开发之ServiceManager一章中我们分析,svcmgr_handler处理从句柄为0的Binder的请求:
    strict_policy = bio_get_string32();
    s = bio_get_string16(); // 就是上面的android.os.IServiceManager
    s = bio_get_string16(); // 就是上面的 media.player
    根据media.player遍历全局链表svclist找到相应的服务,调用bio_put_ref(reply, ptr) 返回目标Binder实体。


    这个waitForResponse()函数是关键:

    status_t IPCThreadState::waitForResponse(Parcel* reply)
    {
    	while(1) {
    		talkWithDriver();	// 输入mOut 输出mIn
    		cmd = mIn.readInt32();
    		switch(cmd) {
    		case BR_REPLY:	
    		{
    			binder_transaction_data tr;
    			mIn.read(&tr, sizeof(tr));
    			if(reply) {
    			reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
    			tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), 
    			tr.offsets_size/sizeof(sizt_t), freeBuffer, this);
    			} else {
    			err = *static_cast<const status_t*>(tr.data.ptr.buffer);
    			freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
    			tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), 
    			tr.offsets_size/sizeof(sizt_t), freeBuffer, this)
    			}
    		}
    		}
    	}
    }
    最后返回的是:return reply.readStrongBinder();进入到Parcel的readStrongBinder()函数
    sp<IBinder> Parcel::readStrongBinder() const
    {
    	sp<IBinder> val;
    	unflatten_binder(ProcessState::self(), *this, &val);
    	return val;
    }
    status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out)
    {
    	const flat_binder_object* flat = in.readObject(false);
    	if(flat) {
    		switch(flat->type) {
    			case BINDER_TYPE_BINDER:
    				*out = static_cast<IBinder*>(flat->cookie);
    				return finish_unflatten_binder(NULL, *flat, in);
    			case BINDER_TYPE_HANDLE:
    				*out = proc->getStrongProxyForHandle(flat->handle);
    				return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);
    		}
    	}
    }

    这里flat->type是BINDER_TYPE_HANDLE,所以调用ProcessState::getStrongProxyForHandle()函数

    sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    {
    	sp<IBinder> result;
    	
    	handle_entry* e = lookupHandleLocked(handle);
    	if(e != NULL) {
    		IBinder* b = e->binder;
    		if(b == NULL || !e->refs->attemptIncWeak(this)) {
    			b = new BpBinder(handle);
    			e->binder = b;
    			if( b ) e->refs = e->getWeakRefs();
    			result = b;
    		} else {
    			result.force_set(b);
    			e->refs->decWeak(this);
    		}
    	}
    	return result;
    }

    这里的handle就是ServiceManager内维护的MediaPlayerService对应的Binder句柄,这个ProcessState根据这个句柄
    new 了一个BpBinder,并将其保存起来,这样下次需要从ServiceManager请求获取到相同句柄的时候就可以直接返回了。
    最后根据这个返回的BpBinder获得MediaPlayerService的代理:
    sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    根据前面ServiceManager一样,最后调用的是IMediaPlayerService的asInterface()宏函数

    android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj)
    {
    	android::sp<IMediaPlayerService> intr;
    	if(obj != NULL ) {
    		intr = static_cast<IMediaPlayerService>(
    			obj->queryLocalInterface(IMediaPlayerService::descriptor).get);
    			if (intr == NULL) {
    				intr = new BpMediaPlayerService(obj);
    			}
    	}
    	return intr;
    }
    

    这样我就获得了一个代理BpMediaPlayerService对象,它的remote()为BpBinder(handle),这个handle就是向服务总共ServiceManager
    查询到的MediaPlayerService对应的Binder句柄。

       下一章我们分析,客户端如何通过这个BpServiceManager代理对象调用服务端MediaPlayerService的业务函数的?

  • 相关阅读:
    java基础16 捕获、抛出以、自定义异常和 finally 块(以及关键字:throw 、throws)
    java基础15 内部类(成员内部类、局部内部类)和匿名内部类
    java基础14 多态(及关键字:instanceof)
    java基础13 接口(及关键字:interface、implements)
    Java 线程控制
    Java 多线程创建和线程状态
    Java New IO
    Java IO流
    Java 集合和泛型
    Java 动态代理
  • 原文地址:https://www.cnblogs.com/pangblog/p/3243947.html
Copyright © 2011-2022 走看看