权力的游戏里经典台词:Android-IPC-Binder(1)
来源:百度文库 编辑:偶看新闻 时间:2024/05/01 17:41:19
本文以IAudioFlinger::setMode函数为例,展示Android IPC是如何工作的。AudioFlinger是Android多媒体服务器程序中一个服务。
Service Manager Run
service_manager为其他进程提供了服务管理的服务,必须在所有服务运行之前启动。
view plaincopy to clipboard?
- // frameworks/base/cmds/servicemanager/service_manager.c
- int main(int argc, char **argv)
- {
- struct binder_state *bs;
- void *svcmgr = BINDER_SERVICE_MANAGER;
- bs = binder_open(128*1024);
- if (binder_become_context_manager(bs)) {
- LOGE("cannot become context manager (%s)/n", strerror(errno));
- return -1;
- }
- svcmgr_handle = svcmgr;
- binder_loop(bs, svcmgr_handler);
- return 0;
- }
它首先打开了/dev/binder驱动,然后调用binder_become_context_manager()函数(其本质是调用ioctl设置BINDER_SET_CONTEXT_MGR)来通知binder内核驱动它是管理者。然后,进入循环,等待其他进程传入的数据。
view plaincopy to clipboard?
- // frameworks/base/cmds/servicemanager/binder.c
- void binder_loop(struct binder_state *bs, binder_handler func)
- {
- int res;
- struct binder_write_read bwr;
- unsigned readbuf[32];
- bwr.write_size = 0;
- bwr.write_consumed = 0;
- bwr.write_buffer = 0;
- readbuf[0] = BC_ENTER_LOOPER;
- binder_write(bs, readbuf, sizeof(unsigned));
- for (;;) {
- bwr.read_size = sizeof(readbuf);
- bwr.read_consumed = 0;
- bwr.read_buffer = (unsigned) readbuf;
- res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
- if (res < 0) {
- LOGE("binder_loop: ioctl failed (%s)/n", strerror(errno));
- break;
- }
- res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
- if (res == 0) {
- LOGE("binder_loop: unexpected reply?!/n");
- break;
- }
- if (res < 0) {
- LOGE("binder_loop: io error %d %s/n", res, strerror(errno));
- break;
- }
- }
- }
注意BINDER_SERVICE_MANAGER的定义
/* the one magic object */
#define BINDER_SERVICE_MANAGER ((void*) 0)
BINDER_SERVICE_MANAGER是service_manager注册的handle。其他进程必须使用它来与service_manager进行对话。
Get IserviceManager
只能通过调用defaultServiceManager()函数来获取一个IserviceManager实例。该函数在IServiceManager.cpp中实现。
view plaincopy to clipboard?
- // frameworks/base/libs/binder/IServiceManager.cpp
- sp
defaultServiceManager() - {
- if (gDefaultServiceManager != NULL)
- return gDefaultServiceManager;
- {
- AutoMutex _l(gDefaultServiceManagerLock);
- if (gDefaultServiceManager == NULL) {
- gDefaultServiceManager = interface_cast
( - ProcessState::self()->getContextObject(NULL));
- }
- }
- return gDefaultServiceManager;
- }
gDefaultServiceManager在libutil中定义,因此任何程序或库使用了libutil库都会有该符号,它在一个进程中唯一。起初gDefaultServiceManager为NULL,于是先调用ProcessState::self()获取一个ProcessState实例。一个进程只有一个ProcessState实例。该ProcessState会打开/dev/binder驱动供IPCThreadState使用。
view plaincopy to clipboard?
- // frameworks/base/libs/binder/ ProcessState.cpp
- ProcessState::ProcessState()
- : mDriverFD(open_driver())
现在,我们有了一个ProcessState实例,让我们看看getContextObject()函数都做了什么。
view plaincopy to clipboard?
- // frameworks/base/libs/binder/ProcessState.cpp
- sp
ProcessState::getContextObject(const sp & caller) - {
- if (supportsProcesses()) {
- return getStrongProxyForHandle(0);
- } else {
- return getContextObject(String16("default"), caller);
- }
- }
因为支持binder驱动(supportsProcesses()函数会判断binder驱动是否打开,以此来检验是否支持binder),所以会执行getStrongProxyForHandle(0)。(Handle 0就是service manager,之前已经提到过的BINDER_SERVICE_MANAGER,后面会进一步解释。)
view plaincopy to clipboard?
- // frameworks/base/libs/binder/ProcessState.cpp
- sp
ProcessState::getStrongProxyForHandle(int32_t handle) - {
- sp
result; - AutoMutex _l(mLock);
- handle_entry* e = lookupHandleLocked(handle);
- if (e != NULL) {
- // We need to create a new BpBinder if there isn't currently one, OR we
- // are unable to acquire a weak reference on this current one. See comment
- // in getWeakProxyForHandle() for more info about this.
- 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 {
- // This little bit of nastyness is to allow us to add a primary
- // reference to the remote proxy when this team doesn't have one
- // but another team is sending the handle to us.
- result.force_set(b);
- e->refs->decWeak(this);
- }
- }
- return result;
- }
在第一次调用时,b为NULL,因此会先创建一个BpBinder实例。BpBinder is a base proxy class for remote binder object.
view plaincopy to clipboard?
- // frameworks/base/libs/binder/BpBinder.cpp
- BpBinder::BpBinder(int32_t handle)
- : mHandle(handle)
- , mAlive(1)
- , mObitsSent(0)
- , mObituaries(NULL)
- {
- LOGV("Creating BpBinder %p handle %d/n", this, mHandle);
- extendObjectLifetime(OBJECT_LIFETIME_WEAK);
- IPCThreadState::self()->incWeakHandle(handle);
- }
IPCThreadState::incWeakHandle将会在输出缓冲区(一个Parcel)中添加一个BC_INCREFS命令。
view plaincopy to clipboard?
- // frameworks/base/libs/binder/IPCThreadState.cpp
- void IPCThreadState::incWeakHandle(int32_t handle)
- {
- LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)/n", handle);
- mOut.writeInt32(BC_INCREFS);
- mOut.writeInt32(handle);
- }
现在getContextObject回返回一个BpBinder实例,改BpBinder实例会通过interface_cast转换为IserviceManager类型。interface_cast定义在IInterface.h头文件中。定义如下:
view plaincopy to clipboard?
- // frameworks/base/include/binder/IInterface.h
- template
- inline sp
interface_cast(const sp & obj) - {
- return INTERFACE::asInterface(obj);
- }
现在让我们看一下IServiceManager的定义。
view plaincopy to clipboard?
- // frameworks/base/include/binder/IServiceManager.h
- class IServiceManager : public Iinterface
- {
- public:
- DECLARE_META_INTERFACE(ServiceManager);
- /**
- * Retrieve an existing service, blocking for a few seconds
- * if it doesn't yet exist.
- */
- virtual sp
getService( const String16& name) const = 0; - /**
- * Retrieve an existing service, non-blocking.
- */
- virtual sp
checkService( const String16& name) const = 0; - /**
- * Register a service.
- */
- virtual status_t addService( const String16& name,
- const sp
& service) = 0; - /**
- * Return list of all existing services.
- */
- virtual Vector
listServices() = 0; - enum {
- GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
- CHECK_SERVICE_TRANSACTION,
- ADD_SERVICE_TRANSACTION,
- LIST_SERVICES_TRANSACTION,
- };
- };
DECLARE_META_INTERFACE宏在IInterface.h头文件中定义如下:
view plaincopy to clipboard?
- // frameworks/base/include/binder/IInterface.h
- #define DECLARE_META_INTERFACE(INTERFACE) /
- static const String16 descriptor; /
- static sp asInterface(const sp
& obj); / - virtual const String16& getInterfaceDescriptor() const; /
- I##INTERFACE(); /
- virtual ~I##INTERFACE();
DECLARE_META_INTERFACE宏声明了两个函数,这两个函数通过在IServiceManager.cpp文件中调用IMPLEMENT_META_INTERFACE宏来实现。
view plaincopy to clipboard?
- // frameworks/base/libs/binder/IServiceManager.cpp
- IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
IMPLEMENT_META_INTERFACE宏定义如下:
view plaincopy to clipboard?
- // frameworks/base/include/binder/IInterface.h
- #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) /
- const String16 I##INTERFACE::descriptor(NAME); /
- const String16& I##INTERFACE::getInterfaceDescriptor() const { /
- return I##INTERFACE::descriptor; /
- } /
- sp I##INTERFACE::asInterface(const sp
& obj) / - { /
- sp intr; /
- if (obj != NULL) { /
- intr = static_cast( /
- obj->queryLocalInterface( /
- I##INTERFACE::descriptor).get()); /
- if (intr == NULL) { /
- intr = new Bp##INTERFACE(obj); /
- } /
- } /
- return intr; /
- } /
- I##INTERFACE::I##INTERFACE() { } /
- I##INTERFACE::~I##INTERFACE() { } /
IServiceManager::asInterface()函数最终会创建一个BpServiceManager实例,并将它返回给用户。BpServiceManager是远程BnServiceManager的一个代理。任何针对IServiceManager的操作最终都会调用BpServiceManager中相应虚函数。
小结:
本节给出了如何获取一个远程对象的代理对象。
假设你要实现你自己的服务IfunnyTest,你需要做以下工作:
- 将DECLARE_META_INTERFACE(FunnyTest)宏放进interface的头文件
- 将IMPLEMENT_META_INTERFACE(Funnytest, “your unique name”)宏放入interface的源文件
- 实现你自己的BpFunnyTest类