通过MediaPlayerService启动作为了解binder驱动的入口.MediaPlayerService是init进程启动的进程,开机时候显示开机动画等.入口源码为framework 目录下main_mediaserver.cpp
文件
启动MediaPlayerService
main_mediaserver.cpp
文件下只有一个main()
函数,我们根据mediaService的启动流程来观察binder驱动如何进行进程间通信
int main(int argc __unused, char** argv)
{
....
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
....
MediaPlayerService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
}
1. ProcessState::self()
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState;
return gProcess;
}
ProcessState::self()
函数,返回一个单例对象.观察ProcessState
的构造方法;
ProcessState::ProcessState()
: mDriverFD(open_driver())
....)
{
...
//在虚拟内存中创建一个1m-8k的内存区域,只读
//#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
...
}
构造函数参数中调用了很多方法,这里只关心open_driver()
,构造方法中还在内核空间中创建了一个1m-8k的空间,这也是binder跨进程通信有最大数据限制的原因.
open_driver()
static int open_driver()
{
...
int fd = open("/dev/binder", O_RDWR);
...
result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
...
}
open()
这里打开/dev/binder
,也就是打开binder驱动,会调用biner驱动中的binder_open()方法;先不管,后面ioctl()
是和biner驱动通信,设置线程最大数,在binder驱动中也是有对应方法.
至此,ProcessState::self()
方法作用就很明显,创建或者返回一个ProcessState
对象,并打开binder驱动并设置该线程的最大binder线程数.
2. defaultServiceManager()
defaultServiceManager()
是一个重要的方法,用来获取一个IServiceManager
对象.
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)
//保证能获取gDefaultServiceManager ,之前会ping servermanger,如未ping通说明servicemanger未创建完成,等待1ms再次ping
sleep(1);
}
}
return gDefaultServiceManager;
}
其中关键代码为ProcessState::self()->getContextObject(NULL));
由上只ProcessState::self()
为ProcessState:对象,到相应ProcessState
类中查看getContextObject()
方法.
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
```java
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
...
if (handle == 0) {
Parcel data;
//ping servicemanager
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
result = b;
}
...
}
首先ping一下servicemanager,ping通以后创建一个BpBinder对象,handle值为0,返回BpBinder对象
defaultServiceManager所实现功能可简化为一下代码,
gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0);)
接下来看interface_cast<IServiceManager>
根据代码宏定义找到
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
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; \
} \
最终defaultServiceManager()
简化为
gDefaultServiceManager =new BpServiceManager(new BpBinder(0);)
new BpBinder(0)
为BpServiceManager
中remote对象.
此方法创建一个servicemanager的代理对象BpServiceManager,用于和servicemanager进行通信.
MediaPlayerService::instantiate();
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
由上可知,调用方法为BpServiceManager
的addService
方法
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
Parcel data, reply;
//binder服务唯一标识符
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
//""media.player""
data.writeString16(name);
// new MediaPlayerService()
data.writeStrongBinder(service);
data.writeInt32(allowIsolated ? 1 : 0);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
看binder驱动传输对象的核心方法之一data.writeStrongBinder(service);
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
...
IBinder *local = binder->localBinder();
if (!local) {
...
} else {
//type
obj.type = BINDER_TYPE_BINDER;
//bbinder 弱引用
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
//bbinder强引用
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
...
return finish_flatten_binder(binder, obj, out);
}
inline static status_t finish_flatten_binder(
const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
{
//将flat_binder_object 写入out
return out->writeObject(flat, false);
}
MediaPlayerService 继承自IBinder
通过binder->localBinder();
获取到MediaPlayerService
的BBinder,并存入flat_binder_object 结构体.写入out,等待传输
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
remote()
为Bpbinder
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
}
调用IPCThreadState::self()->transact()
IPCThreadState::self()
获取IPCThreadState
单例对象.调用transact(方法
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
if (err == NO_ERROR) {
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
...
err = waitForResponse(NULL, NULL);
return err;
}
写入需要传输数据writeTransactionData()
将数据打包成binder_transaction_data
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.ptr = 0;
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
tr.data_size = data.ipcDataSize();
//之前out数据
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
//BC_TRANSACTION
mOut.writeInt32(cmd);
//
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
waitForResponse()
开始发送数据
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
...
err=talkWithDriver()
...
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
binder_write_read bwr;
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
bwr.write_buffer = (uintptr_t)mOut.data();
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0);
将binder_transaction_data 再次包装,包装成binder_write_read
并传入cmdBINDER_WRITE_READ
然后调用ioctl
于驱动通信,根据handle值为0创建servicemanager的代理对象,并将MediaPlayerService
的BBinder引用发送给binder驱动,另一端servicemanager会等待binder驱动发送消息,并根据cmd进行相应操作,这里便是将servicemanager的引用等信息添加到相应的管理结构中.