【Android进阶】Android Binder之ServiceManager注册服务解析1
来源:互联网 发布:spark要用java吗? 编辑:程序博客网 时间:2024/05/21 05:17
下面将通过一个系列来对binder进行解析,虽然之前很多人都已经写过相关的博客,不过还是决定自己来写写,把整个思路理一理,增加自己对binder的认识,也同时希望对大家有所帮助。
首先我们来看的就是ServiceManager注册服务的过程,通过MediaPlayerService的注册过程来讲解整个注册的流程,主要为了看看binder跨进程通信的具体过程。
下面直接上源码。
/frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc, char** argv){ // 1、得到一个ProcessState实例 sp<ProcessState> proc(ProcessState::self()); // 2、获取BpServiceManager对象 sp<IServiceManager> sm = defaultServiceManager(); // 3、注册多媒体服务 MediaPlayerService::instantiate(); // 4、启动Binder线程池 ProcessState::self()->startThreadPool(); // 5、当前线程加入到线程池 IPCThreadState::self()->joinThreadPool();}
一、得到一个ProcessState实例
framework/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self(){ Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } //实例化ProcessState gProcess = new ProcessState; return gProcess;}
使用单例模式,保证每一个进程只有一个ProcessState对象
下面看看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) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1){ if (mDriverFD >= 0) { //采用内存映射函数mmap,给binder分配一块虚拟地址空间 mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { close(mDriverFD); mDriverFD = -1; } }}
下面看看驱动的打开过程
static int open_driver(){ // 打开/dev/binder设备,建立与内核的Binder驱动的交互通道 int fd = open("/dev/binder", O_RDWR); if (fd >= 0) { fcntl(fd, F_SETFD, FD_CLOEXEC); int vers = 0; status_t result = ioctl(fd, BINDER_VERSION, &vers); if (result == -1) { close(fd); fd = -1; } if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { close(fd); fd = -1; } size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; // 通过ioctl设置binder驱动 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;}
二、获取BpServiceManager对象
/frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager(){ // 同样使用的是单例模式 if (gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); while (gDefaultServiceManager == NULL) { // 进入BpServiceManager的创建 // 分为两步: // 1、BpBInder binder = ProcessState::self()->getContextObject(NULL) // 2、interface_cast<IServiceManager>(binder) gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); if (gDefaultServiceManager == NULL) sleep(1); } } return gDefaultServiceManager;}
1、ProcessState::self()->getContextObject(NULL)
/frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self(){ // 同样使用的是单例模式 Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL) { return gProcess; } gProcess = new ProcessState; return gProcess;}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; } // 如果 e->binder为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;}
可以看到最终返回的其实就是new BpBinder(0);
2、interface_cast<IServiceManager>
(new BpBinder(0))
interface_cast方法是一个模板方法,定义在IInterface.h文件中
/frameworks/native/include/binder/IInterface.h
template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){ return INTERFACE::asInterface(obj);}
所以,interface_cast<IServiceManager>
(new BpBinder(0))等价于:
inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){ return IServiceManager::asInterface(obj);}
可以看到实质就是调用了IServiceManager的asInterface方法,即:
IServiceManager::asInterface(new BpBinder(0));
下面在IServiceManager.h看看这个方法的定义
/frameworks/native/libs/binder/IServiceManager.h
class IServiceManager : public IInterface{public: // 这个模板方法实质就是IServiceManager::asInterface(obj) DECLARE_META_INTERFACE(ServiceManager); // ......}
下面我们来看看这个模板方法的定义
/frameworks/native/include/binder/IInterface.h#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(); \-------------------------------------------------------------------------下面是该方法的实现模板#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() { }
下面进行替换可以得到定义为:
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(); \-------------------------------------------------------------------------IServiceManager::asInterface(obj)的实现为:const android::String16 IServiceManager::descriptor(NAME); \const android::String16& \ IServiceManager::getInterfaceDescriptor() const { \ return IServiceManager::descriptor; \} \android::sp<IServiceManager> 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) { \ intr = new BpServiceManager(obj); \ } \ } \ return intr; \} \I##INTERFACE::I##INTERFACE() { } \I##INTERFACE::~I##INTERFACE() { }
从上面可以看到实质是new BpServiceManager(obj)创建了一个BpServiceManager对象。
从上面分析可以知道:
interface_cast<IServiceManager>
(binder)实质等价为:
new BpServiceManager(new BpBinder(0))
也就是说 defaultServiceManager()方法最终返回的对象为BpServiceManager对象。
下面看看IServiceManager.cpp中BpServiceManager类的构造方法
/frameworks/native/libs/binder/IServiceManager.cpp
class BpServiceManager : public BpInterface<IServiceManager>{public: BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { } //......}
可以看到BpServiceManager继承了BpInterface方法,并且同时在构造函数中也调用了BpInterface的构造方法。
BpServiceManager(new BpBinder(0))->BpInterface<IServiceManager>
(new BpBinder(0))
下面看看BpInterface的构造函数
/frameworks/native/include/binder/IInterface.h
template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public: BpInterface(const sp<IBinder>& remote);protected: virtual IBinder* onAsBinder();};-------------------------------------------------------------------------template<typename INTERFACE>inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote){}
它是一个模板方法,替换之后为:
class BpInterface : public IServiceManager, public BpRefBase{public: BpInterface(const sp<IBinder>& remote);protected: virtual IBinder* onAsBinder();};----------------------------------------------------------------------------inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote) : BpRefBase(remote){}
可以看到BpInterface继承了IServiceManager和BpRefBase,并且调用了BpRefBase的构造方法
BpServiceManager(new BpBinder(0))->BpInterface<IServiceManager>
(new BpBinder(0))–>BpRefBase(new BpBinder(0))
下面看看BpRefBase的构造方法
/frameworks/native/libs/binder/Binder.cpp
BpRefBase::BpRefBase(const sp<IBinder>& o) // 这里实质就是将new BpBinder(0)这个对象复制给mRemote // 即mRemote持有对BpBinder对象的引用 : mRemote(o.get()), mRefs(NULL), mState(0){ extendObjectLifetime(OBJECT_LIFETIME_WEAK); if (mRemote) { mRemote->incStrong(this); // Removed on first IncStrong(). mRefs = mRemote->createWeak(this); // Held for our entire lifetime. }}
上面类直接的关系图如下所示:
三、注册多媒体服务
当我们拿到这个BpServiceManager对象之后,相当于我们就拿到了ServiceManager的远程代理对象,使用BpServiceManager这个代理对象我们就可以实现对ServiceManager的远程调用,下面我们通过注册多媒体服务来看看它的调用流程。
/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
void MediaPlayerService::instantiate() { defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());}
上面已经说过defaultServiceManager()是一个单例方法,返回的是BpServiceManager对象,下面看看该对象的addService方法,它实现的是对远程ServiceManager对象的addService方法的调用。
/frameworks/native/libs/binder/IServiceManager.cpp
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); status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode() : err;}
remote()方法返回的就是前面设传递进去的BpBinder对象,也就是说最终会将调用的数据进行打包到Parcel对象中,然后调用BpBinder对象的transact方法。
/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) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; } return DEAD_OBJECT;}
可以看到最终调用的是IPCThreadState对象的transact方法。
上面的调用关系图如下:
下面我们来看看具体的调用过程。
/frameworks/native/libs/binder/IPCThreadState.cpp
IPCThreadState* IPCThreadState::self(){ if (gHaveTLS) {restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if (st) return st; return new IPCThreadState; } if (gShutdown) return NULL; pthread_mutex_lock(&gTLSMutex); if (!gHaveTLS) { if (pthread_key_create(&gTLS, threadDestructor) != 0) { pthread_mutex_unlock(&gTLSMutex); return NULL; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart;}
实质就是获取一个IPCThreadState对象,这是一个线程相关的对象,每个线程只有一个IPCThreadState对象,下面看看IPCThreadState的构造方法
IPCThreadState::IPCThreadState() : mProcess(ProcessState::self()), mMyThreadId(androidGetTid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0){ pthread_setspecific(gTLS, this); clearCaller(); mIn.setDataCapacity(256); mOut.setDataCapacity(256);}
每个IPCThreadState对象都有一个mIn和一个mOut,其中mIn接收来自Binder设备的数据,mOut存放发往Binder设备的数据。
另外,我们可以看到在IPCThreadState中有一个mProcess变量它对应的就是ProcessState的引用,我们知道,在ProcessState中我们在前面打开过binder驱动。
下面我们来具体看看IPCThreadState对象的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; IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand " << handle << " / code " << TypeCode(code) << ": " << indent << data << dedent << endl; } if (err == NO_ERROR) { LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(), (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY"); err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); } if (err != NO_ERROR) { if (reply) reply->setError(err); return (mLastError = err); } if ((flags & TF_ONE_WAY) == 0) { #if 0 if (code == 4) { // relayout ALOGI(">>>>>> CALLING transaction 4"); } else { ALOGI(">>>>>> CALLING transaction %d", code); } #endif if (reply) { err = waitForResponse(reply); } else { Parcel fakeReply; err = waitForResponse(&fakeReply); } #if 0 if (code == 4) { // relayout ALOGI("<<<<<< RETURNING transaction 4"); } else { ALOGI("<<<<<< RETURNING transaction %d", code); } #endif IF_LOG_TRANSACTIONS() { TextOutput::Bundle _b(alog); alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand " << handle << ": "; if (reply) alog << indent << *reply << dedent << endl; else alog << "(none requested)" << endl; } } else { err = waitForResponse(NULL, NULL); } return err;}
上面过程主要有两步:
1、writeTransactionData方法进行数据写入
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.handle = handle; tr.code = code; tr.flags = binderFlags; tr.cookie = 0; tr.sender_pid = 0; tr.sender_euid = 0; const status_t err = data.errorCheck(); if (err == NO_ERROR) { tr.data_size = data.ipcDataSize(); tr.data.ptr.buffer = data.ipcData(); tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t); tr.data.ptr.offsets = data.ipcObjects(); } else if (statusBuffer) { tr.flags |= TF_STATUS_CODE; *statusBuffer = err; tr.data_size = sizeof(status_t); tr.data.ptr.buffer = statusBuffer; tr.offsets_size = 0; tr.data.ptr.offsets = NULL; } else { return (mLastError = err); } mOut.writeInt32(cmd); //cmd = BC_TRANSACTION mOut.write(&tr, sizeof(tr)); return NO_ERROR;}
上面的过程就是将addService的请求信息写入到mOut中。
2、waitForResponse方法进行请求发送并等待回复
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){ int32_t cmd; int32_t err; while (1) { if ((err=talkWithDriver()) < NO_ERROR) break; err = mIn.errorCheck(); if (err < NO_ERROR) break; if (mIn.dataAvail() == 0) continue; cmd = mIn.readInt32(); IF_LOG_COMMANDS() { alog << "Processing waitForResponse Command: " << getReturnString(cmd) << endl; } switch (cmd) { case BR_TRANSACTION_COMPLETE: if (!reply && !acquireResult) goto finish; break; case BR_DEAD_REPLY: err = DEAD_OBJECT; goto finish; case BR_FAILED_REPLY: err = FAILED_TRANSACTION; goto finish; case BR_ACQUIRE_RESULT: { ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT"); const int32_t result = mIn.readInt32(); if (!acquireResult) continue; *acquireResult = result ? NO_ERROR : INVALID_OPERATION; } goto finish; case BR_REPLY: { binder_transaction_data tr; err = mIn.read(&tr, sizeof(tr)); ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY"); if (err != NO_ERROR) goto finish; if (reply) { if ((tr.flags & TF_STATUS_CODE) == 0) { reply->ipcSetDataReference( reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), freeBuffer, this); } else { err = *static_cast<const status_t*>(tr.data.ptr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); } } else { freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data_size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(size_t), this); continue; } } goto finish; default: err = executeCommand(cmd); if (err != NO_ERROR) goto finish; break; } }finish: if (err != NO_ERROR) { if (acquireResult) *acquireResult = err; if (reply) reply->setError(err); mLastError = err; } return err;}
上面就是在talkWithDriver中,把mOut发出去,然后从driver中读到回复数据放到mIn中了。这样就完成了一次跨进程的操作。
前面我们说到,我们把mOut发出去,那边另一端肯定会取出这个数据,然后根据这个数据的需要完成知道的操作,完成之后把需要返回的数据再写入到driver中,这样我们这端就可以从driver中读到回复数据放到mIn中,完成一次跨进程的操作,我们前面所分析的整个过程是客户端发起的过程,那么另一端就是服务端,我们下面就要分析服务端是怎么从driver获取到mOut数据,执行相应的操作,然后把返回数据再写回到driver,让客户端来获取。
- 【Android进阶】Android Binder之ServiceManager注册服务解析1
- android binder机制,注册系统服务--服务端servicemanager binder驱动
- android binder机制,注册系统服务---服务端servicemanager
- 【android】binder机制-servicemanager
- Android - Binder机制 - ServiceManager
- Android binder -serviceManager
- android binder 机制 (ServiceManager)
- android binder 机制 (ServiceManager)
- Android------Binder servicemanager篇
- Android Binder机制浅析之ServiceManager
- Android Binder机制浅析之ServiceManager
- Android笔记 - Binder之守护进程servicemanager
- Android笔记 - Binder之servicemanager代理对象
- 五、Android Binder机制浅析之ServiceManager
- Android如何注册服务到ServiceManager?
- android binder --- ServiceManager启动分析
- Android 之 ServiceManager与服务管理
- Android 之 ServiceManager与服务管理
- 2017/11/9 c语言学习之路
- 手机格式,省份证格式,过滤图标,过滤qq图像
- 新 CentOS 6.5 6.9 环境下搭建直播模拟测试环境 ffmpeg+nginx=rtmp (傻瓜式环境搭建)
- Javacore分析
- PHP面向对象的程序设计2
- 【Android进阶】Android Binder之ServiceManager注册服务解析1
- easyUI入门
- android jar转dex
- CentOS命令大全
- 字符串转换
- ubuntu16修改mysql默认字符集为utf8
- git版本控制常用命令
- 中文大写日期转换函数
- linux网络工具iproute2的使用简介