Framework binder驱动(一)MediaPlayerService 启动

2022-08-01,,,

通过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());
}

由上可知,调用方法为BpServiceManageraddService方法

  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的引用等信息添加到相应的管理结构中.

本文地址:https://blog.csdn.net/WGHCWC/article/details/107367048

《Framework binder驱动(一)MediaPlayerService 启动.doc》

下载本文的Word格式文档,以方便收藏与打印。