Binder基本概念流程学习

时间:2022-12-19 19:50:28

 

一 Media Service进程启动

Init.rc中描述的service对应linux 的进程:

Media进程定义:

service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc
ioprio rt
4

servicemanager 进程定义:

service servicemanager /system/bin/servicemanager
class core
user system
  group system

 

  Media中有很多Native Service(AudioFlinger MediaPlayerService CameraService 
AudioPolicyService等),整个Android(native或者framework)的Service都需要加入
servicemanager中进行统一管理。
  那么Media Process 与ServiceManager Process是如何进行通信的呢——Binder.
通过Media Process中使用binder进行完成IPC过程,学习Binder的概念和使用方法。

\frameworks\av\media\mediaserver\ main_mediaserver.cpp:

int main(int argc, char** argv)
{
//创建ProcessState 当前进程属性
sp<ProcessState> proc(ProcessState::self());

//IServiceManager对象
sp<IServiceManager> sm = defaultServiceManager();

//初始化MediaPlayerService服务对象
MediaPlayerService::instantiate();
……

//启动进程的线程池
ProcessState::self()->startThreadPool();
//执行线程消息循环
IPCThreadState::self()->joinThreadPool();
}

  Sp:指针运算符和普通运算符的重载 StrongPointer。

二 Media Process执行过程

1 ProcessState对象创建

当前进程的状态属性,对象创建:

sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess
= new ProcessState;
return gProcess;
}

ProcessState构造函数:

ProcessState::ProcessState()
: mDriverFD(open_driver())
//打开binder驱动设备
, mVMStart(MAP_FAILED)
, mManagesContexts(
false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(
false)
, mThreadPoolSeq(
1)
{
if (mDriverFD >= 0) {
//将binder的fd映射到当前进程虚拟空间地址中 与binder进行交互
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,
        MAP_PRIVATE
| MAP_NORESERVE, mDriverFD, 0);
}
}

打开binder设备:

static int open_driver()
{
//打开binder设备驱动
int fd = open("/dev/binder", O_RDWR);
if (fd >= 0) {
//bidner最大支持线程数
size_t maxThreads = 15;
result
= ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
}
return fd;
}

ProcessState对象创建过程所做的事:
  打开/dev/binder设备,得到binder设备的fd;
  将bidner设备fd映射到当前进程虚拟地址空间建立交互的通道;

2 IServiceManager对象创建
  sp<IServiceManager> sm = defaultServiceManager();
为什么需要一个IServiceManager对象呢,这个类是个抽象提供接口

class IServiceManager : public IInterface
{
virtual sp<IBinder> getService( const String16& name) const = 0;
virtual status_t addService( const String16& name,
const sp<IBinder>& service,
bool allowIsolated = false) = 0;
……
};

  通过IServiceManager派生对象操作将Service加入到ServiceManager中.

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;
}
 

ProcessState::self()->getContextObject(NULL):得到一个IBinder对象

  ProcessState::self()刚才所创建的ProcessState对象。

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对应的handle_entry
//若没有则创建一个 handle == 0
handle_entry* e = lookupHandleLocked(handle);

if (e != NULL) {
IBinder
* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
//handle_entry对象成员初始化 创建handle=0的BpBinder
b = new BpBinder(handle);
e
->binder = b;
if (b) e->refs = b->getWeakRefs();
result
= b;
}
}
return result;
}

  handle_entry是什么呢?

      struct handle_entry {
IBinder
* binder;
RefBase::weakref_type
* refs;
};

  也就是说ProcessState 有一个表Vector<handle_entry>mHandleToObject;

表里面的每一项存储了一个binder,每一个binder对应一个handle。

  Binder基本概念流程学习

  Handle = 0是什么,句柄? 代表谁的句柄——ServiceManager在binder中的资源。
从ProcessState::self()->getContextObject(NULL)得到一个 IBinder——BpBinder(0);
于是得到:
  gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));

使用interface_cast将IBinder实例转化成IServiceManager实例。

3 interface_cast函数

\frameworks\native\include\binder\IInterface.h:

interface_cast是个内联模板函数: 

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里面去看看是如何实现的

4 IServiceManager类

\frameworks\native\include\binder\IServiceManager.h:

IServiceManager是一个抽象类:

class IServiceManager : public IInterface
{
  
public:
//宏声明
DECLARE_META_INTERFACE(ServiceManager);
virtual sp<IBinder> getService( const String16& name) const = 0;
virtual status_t addService( const String16& name,
const sp<IBinder>& service,
bool allowIsolated = false) = 0;
……
}

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(); \ 

替换成IServiceManager:

//实现时传入:android.os.IServiceManager
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();

实现\frameworks\native\include\binder\IServiceManager.cpp:

IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");

IMPLEMENT_META_INTERFACE实现:
看一下asInterface接口:

#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; \
}                                       \

替换成IServiceManager:

android::sp<IServiceManager> IServiceManager::asInterface( 
const android::sp<android::IBinder>& obj)
{
//obj BpBinder实例
android::sp<IServiceManager> intr;
if (obj != NULL) {
//返回NULL
intr = static_cast<IServiceManager*>(
obj
->queryLocalInterface(
IServiceManager::descriptor).
get());
if (intr == NULL) {
intr
= new BpServiceManager(obj);
}
}
return intr;
}

这里得到IServiceManager 实例:

  BpServiceManager:new BpServiceManager(new BpBinder(0));

5 BpServiceManager 和 BpInterface类

\frameworks\native\libs\binder\ IServiceManager.cpp:BpServiceManager

class BpServiceManager : public BpInterface<IServiceManager>
{
public:
//impl就是 new BpBinder(0)
BpServiceManager(const sp<IBinder>& impl)
: BpInterface
<IServiceManager>(impl)
{
}

virtual sp<IBinder> checkService(const String16& name) const
{
……
remote()
->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
}

virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
……
remote()
->transact(ADD_SERVICE_TRANSACTION, data, &reply);
}
}

\frameworks\native\include\binder\ IInterface.h:模板类BpInterface

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase // INTERFACE IServiceManager
{
  
public:
    BpInterface(
const sp<IBinder>& remote);
  
protected:
    virtual IBinder* onAsBinder();
};

BpInterface构造函数:

template<typename INTERFACE>
inline BpInterface
<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}

BpRefBase构造函数:

BpRefBase::BpRefBase(const sp<IBinder>& o)
: mRemote(o.
get()), mRefs(NULL), mState(0)
{
  
// IBinder mRemote 指向 o.get() :new BpBinder(0)
}

  gDefaultServiceManager = interface_cast<IServiceManager>(BpBinder(0));
实际为:
  gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
Bn代表Binder Native Bp代表Binder Proxy
BpServiceManager代理的BpBinder实例 BpBinder代理的handle(0)

这个关系有些复杂,看一下类继承结构图:

  Binder基本概念流程学习


  上面这个结构看起来感觉很熟悉——Bridge模式。将Binder数据交互和功能处理桥接起来。

在Media Process 的main函数中通过:

  sp<IServiceManager> sm = defaultServiceManager();
  我们得到了sm:是BpServiceManager对象。

三 MediaPlayerService加入到ServiceManager中

回到main函数中:

int main(int argc, char** argv)
{
//创建ProcessState 当前进程属性
sp<ProcessState> proc(ProcessState::self());

//IServiceManager对象
sp<IServiceManager> sm = defaultServiceManager();

//初始化MediaPlayerService服务对象
MediaPlayerService::instantiate(); //执行到这里
……

//启动进程的线程池
ProcessState::self()->startThreadPool();
//执行线程消息循环
IPCThreadState::self()->joinThreadPool();
}

1 MediaPlayerService初始化过程

void MediaPlayerService::instantiate() {
  
// defaultServiceManager就是上面所述得到的BpServiceManager对象
  defaultServiceManager()->addService(
    String16(
"media.player"), new MediaPlayerService());
}

BpServiceManager添加Service:

virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
//生成数据包Parcel
Parcel data, reply;
// Write RPC headers 写入Interface名字 得到“android.os.IServiceManager”
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
//写入Service名字 “media.player”
data.writeString16(name);
//写入服务
data.writeStrongBinder(service);
data.writeInt32(allowIsolated
? 1 : 0);
// remote()返回BpBinder对象
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}

remote()->transact 到BpBinder中:

status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
//到当前进程IPCThreadState中 mHandle=0
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}

 

2 IPCThreadState中写入数据到Binder设备过程

IPCThreadState::self()->transact过程:

status_t IPCThreadState::transact(int32_t handle,
uint32_t code,
const Parcel& data,
Parcel
* reply, uint32_t flags)
{
status_t err
= data.errorCheck();

flags
|= TF_ACCEPT_FDS;
//将数据转化成binder_transaction_data 写入到Parcel实例mOut中
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
//写入数据
err = waitForResponse(reply);
return err;
}

status_t IPCThreadState::waitForResponse(Parcel
*reply, status_t *acquireResult)
{
while (1) {
//将数据写入到Binder设备中
talkWithDriver();
……
}
return err;
}

status_t IPCThreadState::talkWithDriver(
bool doReceive)
{
//将数据封装成binder_write_read结构
binder_write_read bwr;

do {
//将数据写入到所打开的Binder设备中
ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)
……

}
while (err == -EINTR);
return NO_ERROR;
}

  将MediaPlayerService加入到ServiceManager中,

这里就通过BpServiceManager的AddService将数据写入到Binder设备传递给ServiceManager。

继续Media Process过程

四 Media Process消息循环

int main(int argc, char** argv)
{
//启动进程的线程池
ProcessState::self()->startThreadPool(); //走到了这里

//执行线程消息循环
IPCThreadState::self()->joinThreadPool();
}


1 创建工作者线程

startThreadPool:\frameworks\native\libs\binder\ ProcessState.cpp:

void ProcessState::startThreadPool()
{
spawnPooledThread(
true);
}

void ProcessState::spawnPooledThread(bool isMain)
{
//创建PoolThread对象 并run ,非线程
sp<Thread> t = new PoolThread(isMain);
  t
->run(buf);
}

  PoolThread继承Thread

执行Thread的run函数:

status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
//创建线程mThread _threadLoop
bool res;
res
= createThreadEtc(_threadLoop,
this, name, priority, stack, &mThread);

return NO_ERROR;
}

现在有两个线程:主线程和mThread线程

mThread线程执行:_threadLoop

int Thread::_threadLoop(void* user)
{
Thread
* const self = static_cast<Thread*>(user);
do {
//调用子类的threadLoop
result = self->threadLoop();
……
}
while(strong != 0);
return 0;
}

class PoolThread : public Thread
{
protected:
virtual bool threadLoop()
{
IPCThreadState::self()
->joinThreadPool(mIsMain);
return false;
}
};

2 进程间通信消息循环过程

消息循环:

void IPCThreadState::joinThreadPool(bool isMain)
{
mOut.writeInt32(isMain
? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
//消息循环
do {
int32_t cmd;
//从binder设备中读取命令
result = talkWithDriver();
if (result >= NO_ERROR) {
cmd
= mIn.readInt32();
//执行命令
result = executeCommand(cmd);
}
……
}
while (result != -ECONNREFUSED && result != -EBADF);

mOut.writeInt32(BC_EXIT_LOOPER);
talkWithDriver(
false);
}

命令执行:

status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder
* obj;
RefBase::weakref_type
* refs;
switch (cmd) {
case BR_DECREFS:
break;
case BR_ATTEMPT_ACQUIRE:
break;
case BR_TRANSACTION:
  binder_transaction_data tr;
result
= mIn.read(&tr, sizeof(tr));
if (tr.target.ptr) {
//将目标对象转化成BBinder
sp<BBinder> b((BBinder*)tr.cookie);
//调用BBinder的transact 函数
const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
}
break;
……
default:
}
return result;
}

  binder_transaction_data.cookie:target object cookie目标对象,这个target object是指那个呢?

在Media Process里面有几个Service:AudioFlinger、MediaPlayerService、CameraService等。

这个目标是这其中Service中的一个,假设目标对象为为MediaPlayerService,那为何要转化成BBinder呢?

3 Service对命令的处理

  线程从binder接收到消息命令,将命令传递给Service处理。将目标对象转化成BBinder,然后调度此命令;

命令从远端传递到本地端进行处理,每个Service都对应BnXXX对象来处理远端BpXXX传来的命令。
  sp<BBinder> b((BBinder*)tr.cookie);
  const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
  这里b代表某个Service:假设为MediaPlayerService;弄清楚执行过程,要弄清楚类继承关系。

    Binder基本概念流程学习


  本地端BnMediaPlayerService消息处理过程:真正的对象是MediaPlayerService实例。
从BBinder ->transact开始传递:

status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
//onTransact是个virtual函数 派生类BnMediaPlayerService重写
err = onTransact(code, data, reply, flags);
return err;
}

status_t BnMediaPlayerService::onTransact(
uint32_t code,
const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code) {
case CREATE: {
pid_t pid
= data.readInt32();
sp
<IMediaPlayerClient> client =
interface_cast
<IMediaPlayerClient>(data.readStrongBinder());
//create是个virtual函数 派生类MediaPlayerService重写
sp<IMediaPlayer> player = create(pid, client, audioSessionId);
//创建player写入到数据包中 传回
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
}
break;
……
default:
return BBinder::onTransact(code, data, reply, flags);
}
}

 

可以看看Client类继承关系结构图:

    Binder基本概念流程学习

  看到这个跟上面的MediaPlayerService继承关系非常的相似,

  这个结构也非常的熟悉——Adapter模式;将binder消息交互和命令处理适配到一起。

五 Client端与Service端交互

  Client对Service进行使用Binder通信,是得到一个Service BnXXX端对象的代理,在Client 为BpXXX代理,

然后使用此代理进行相关的操作. 前面在使用ServiceManager就是此种方式进行。

  实际上通信的基础是Binder,Proxy不过是在Binder上进行了一层封装,封装了对binder驱动的底层操作,使具有面向对象的特性。

任意两个进程通过Binder进行通信,就是先得到另一个进程的binder标识,通过此binder进行数据交换。

    Binder基本概念流程学习

1 新增加一个服务
看下面media Palyer类继承结构。
实现Bn端类继承结构:

    Binder基本概念流程学习


实现Bp端类继承结构

    Binder基本概念流程学习

 

可以看到 :

  •   需要定义服务公共接口IMediaPlayerService;
  •   实现服务Bn端 派发消息BnMediaPlayerService;
  •   实现服务的命令处理MediaPlayerService;
  •   实现服务代理BpMediaPlayerService;

2 Client获取Service服务

  Native Service以及framework Service都是加入到ServiceManger中,

不管native端还是Framework端得Service 其实都是要满足上面远程对象代理结构。

native端获取service:

//获取ServiceManager的代理对象
sp<IServiceManager> sm = defaultServiceManager();
//通过ServiceManager获取media Service binder
binder = sm->getService(String16("media.player"));
//将binder封装 构造media Service代理对象 BpMediaPlayerService
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

framework层的service,借助AIDL文件,实现跨进程的通信:

  所有framework端service想要作为公共的服务,被别的应用程序调用,都要实现AIDL文件,服务要继承该AIDL文件内部类Stub。
其实AIDL文件是对Framework中service作为进程通信的框架的封装,系统自动生成中间需要的代码和步骤,统一结构:还是binder代理,服务代理。

下面看看PowerManagerService实现。
PowerManagerService服务:

\frameworks\base\services\java\com\android\server\PowerManagerService.java

public class PowerManagerService extends IPowerManager.Stub……
{
  
public void goToSleep(long time){
    ……
  }
};

AIDL文件:\frameworks\
base\core\java\android\os\IPowerManager.aidl
interface IPowerManager
{
  
void goToSleep(long time);
  ……
}

AIDL对应的Java文件:
  AIDL会自动生成一个对应的Java的interface文件,看看这个接口文件。
  AIDL自动生成对应java文件位置:\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates\src\core\java\android\os

public interface IPowerManager extends android.os.IInterface {
//IPowerManager 内部类 Stub
public static abstract class Stub extends android.os.Binder implements
android.os.IPowerManager {
public static android.os.IPowerManager asInterface(
android.os.IBinder obj)
{
//生成一个Proxy对象
return new android.os.IPowerManager.Stub.Proxy(obj);
}
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data,
android.os.Parcel reply,
int flags)
{
switch (code) {
case TRANSACTION_goToSleep:
this.goToSleep(_arg0);
return true;
……
}
}
//Stub内部类Proxy
private static class Proxy implements android.os.IPowerManager {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote
= remote;
}
public void goToSleep(long time)
{
//将数据打包成Parcel
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply
= android.os.Parcel.obtain();
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeLong(time);
//传输数据到binder 到相关的Service 进程
// IPCThreadState::transact方法中完成
mRemote.transact(Stub.TRANSACTION_goToSleep, _data, _reply,0);
_reply.readException();
}
}
}
//goToSleep接口对应的ID
static final int TRANSACTION_goToSleep = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
//接口
public void goToSleep(long time);
}

看下其中类结构:

    Binder基本概念流程学习


AIDL自动生成对应的java文件,将结构过程进行了统一,自动生成中间代码。

Application获取用Service:

IPowerManager m mPowerManagerService;
//获取service的bingder
IBinder binder = ServiceManager.getService("power");
//创建service代理对象
mPowerManagerService = IPowerManager.Stub.asInterface(binder);
//调用接口
mPowerManagerService.goToSleep();

Native Service和 Framework Service结构方式基本一致的。

 

进程间通信Linux系统已经提供了很多方式,比如Socket,为什么Android非要另辟蹊径,设计了Binder呢?

  可以阅读一下:http://www.cnblogs.com/bastard/archive/2012/10/17/2728155.html


  Game Over !

参考文档:
  http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
  http://blog.csdn.net/maxleng/article/details/5490770

注:

 

  “我们其实还一部分没有研究,就是同一个进程之间的对象传递与远程传递是区别的。同一个进程间专递服务地和对象,

  就没有代理BpBinder产生,而只是对象的直接应用了。应用程序并不知道数据是在同一进程间传递还是不同进程间传递,

  这个只有内核中的Binder知道,所以内核Binder驱动可以将Binder对象数据类型从BINDER_TYPE_BINDER修改为

  BINDER_TYPE_HANDLE或者BINDER_TYPE_WEAK_HANDLE作为引用传递。”  ——来自上述地址

  这个可以看到在SystemServer运行的Service之间使用时,直接转化成了对应的对象,而不是通过代理。