Binder进程间通信系统第三篇-----Binder进程间通信之 MediaServer 简析

本文学习拜读自邓凡平老师的 《深入理解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 提供的业务逻辑函数了。


三 MediaServer 之 ServiceManager 简析

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值